日常系列LeetCode《16·二叉树1》

Posted 常某某的好奇心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日常系列LeetCode《16·二叉树1》相关的知识,希望对你有一定的参考价值。

数据规模->时间复杂度

<=10^4 😮(n^2)
<=10^7:o(nlogn)
<=10^8:o(n)
10^8<=:o(logn),o(1)

内容

lc 144 :二叉树的前序遍历
https://leetcode.cn/problems/binary-tree-preorder-traversal/
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶:
递归算法很简单,你可以通过迭代算法完成吗?

#方案一:使用栈-根->先入右->再入左
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:return []
        res,stack=list(),[] #res:数值 stack:节点
        stack.append(root)
        while stack:
        	#根
            curr=stack.pop()
            res.append(curr.val)
            #右-左
            if curr.right:stack.append(curr.right)
            if curr.left:stack.append(curr.left)
        return res

lc 94【top100】:二叉树的中序遍历
https://leetcode.cn/problems/binary-tree-inorder-traversal/
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶:
递归算法很简单,你可以通过迭代算法完成吗?

#方案一:使用栈-遍历左
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:return []
        res,stack=[],list()
        curr=root
        while curr or stack:
            #左遍历
            while curr:
                stack.append(curr)
                curr=curr.left
            #'根'
            node=stack.pop()
            res.append(node.val)
            #右
            curr=node.right
        return res

lc 145 :二叉树的后序遍历
https://leetcode.cn/problems/binary-tree-postorder-traversal/
提示:
树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶:
递归算法很简单,你可以通过迭代算法完成吗?

#使用栈
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:return []
        res,stack=list(),[] #res:数值 stack:节点
        stack.append(root)
        while stack:
            curr=stack.pop()
            res.append(curr.val)
            #注:次序
            if curr.left:stack.append(curr.left)
            if curr.right:stack.append(curr.right)
        res.reverse()
        return res

二叉树前中后序的递归实现

#前序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res=[]
        self.preorder(root,res)
        return res
    
    def preorder(self,node,res): #这种写法:防止每次递归,节点存于不同结果集/或防于结果集的累加输出
        if not node:return 
        #‘根’
        res.append(node.val)
        #解决‘左’
        self.preorder(node.left,res)
        #解决‘右’
        self.preorder(node.right,res)

#中序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res=[]
        self.inorder(root,res)
        return res
    
    def inorder(self,node,res):
        #
        if not node:return 
        #
        self.inorder(node.left,res)
        res.append(node.val)
        self.inorder(node.right,res)
        
#后序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res=[]
        self.postorder(root,res)
        return res
    
    def postorder(self,node,res):
        #
        if not node:return 
        #
        self.postorder(node.left,res)
        self.postorder(node.right,res)
        res.append(node.val)

lc 102【剑指 32-2】【top100】: 二叉树的层序遍历
https://leetcode.cn/problems/binary-tree-level-order-traversal/
提示:
树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

#(优)方案一:使用队列
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:return []
        #
        res=[]
        queue=deque()
        queue.append(root)
        while queue:
            #key
            curr_res=[] #记录当前层
            for i in range(len(queue)):
            	#
                curr = queue.popleft()
                curr_res.append(curr.val)
                #
                if curr.left:queue.append(curr.left)
                if curr.right:queue.append(curr.right)
            res.append(curr_res)
        return res
        
#方案二:利用前序遍历(迭代)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:return []
        #
        res=[]
        stack=list()
        stack.append([root,0])
        while stack:
            curr,currlevel = stack.pop()
            
            ###key:按level处理
            #增层
            if len(res) < currlevel+1 :
                res.append([curr.val]) 
            #在对应层增项
            else:
                res[currlevel].append(curr.val)
            
            ###
            if curr.right:stack.append([curr.right,currlevel+1])
            if curr.left:stack.append([curr.left,currlevel+1])   
        return res
        
#(优)方案三:利用前序(递归)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:return []
        #
        res=[]
        self.preorder(root,0,res)
        return res

    def preorder(self,node,currlevel,res):
        if not node:return 
        # 
        ###key:按level处理当前节点
        curr=node
        #增层
        if len(res) < currlevel+1 :
            res.append([curr.val]) 
        #在对应层增项
        else:
            res[currlevel].append(curr.val)
            
        #
        self.preorder(curr.left,currlevel+1,res) 
        self.preorder(curr.right,currlevel+1,res)

lc 107 :二叉树的层序遍历 II
https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/
提示:
树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

#方案一:使用队列+reverse()
#方案二:利用前序遍历(迭代)+ reverse()

#方案三:利用前序(递归)+ reverse()
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        res=[]
        self.preorder(root,0,res)
        res.reverse()
        return res
    
    def preorder(self,node,currlevel,res):
        if not node:return

        #
        if len(res)<currlevel+1:
            res.append([node.val])
        else:
            res[currlevel].append(node.val)
        #
        self.preorder(node.left,currlevel+1,res)
        self.preorder(node.right,currlevel+1,res)    

#############################################################

DFS 和 BFS 概念理解
DFS(栈): 前中后序遍历->先进后出
BFS(对列): 层序遍历->先进先出

lc 104【剑指 55-1】【top100】:二叉树的最大深度
https://leetcode.cn/problems/maximum-depth-of-binary-tree/
说明: 叶子节点是指没有子节点的节点。

#方案一:BFS:
#层序遍历
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        #
        queue=deque()
        queue.append(root)
        res=[]
        level=0
        while queue:
            #curr_res=[]
            for i in range(len(queue)):
                curr=queue.popleft()
                #curr_res.append(curr.val)
                #
                if curr.left:queue.append(curr.left)
                if curr.right:queue.append(curr.right)
            #res.append(curr_res)
            level+=1
        return level

#方案二:DFS
#前序遍历(迭代)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        #
        res=0
        stack=[]
        stack.append([root,1])
        while stack:
            curr,currlevel=stack.pop()
            res=max(res,currlevel)#key
            #
            if curr.right:stack.append([curr.right,currlevel+1])
            if curr.left:stack.append([curr.left,currlevel+1])
        return res

#前序遍历(递归)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        #
        self.res=0
        self.preorder(root,1)
        return self.res
    
    def preorder(self,node,currlevel):
        if not node:return 
        self.res=max(self.res,currlevel)

        self.preorder(node.left,currlevel+1)
        self.preorder(node.right,currlevel+1)

#后序遍历
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        return self.postorder(root)
    
    def postorder(self,node):
        if not node:return 0 
        #
        left=self.postorder(node.left)
        right=self.postorder(node.right)
        return max(left,right)+1   

lc 543【top100】:二叉树的直径
https://leetcode.cn/problems/diameter-of-binary-tree/
注意:两结点之间的路径长度是以它们之间边的数目表示。

#DFS
#后序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        self.res=0
        self.postorder(root)
        return self.res

    def postorder(self,node):
        if not node:return 0
        left=self.postorder(node.left)
        right=self.postorder(node.right)
        #key:左分支+右分支
        self.res=max(self.res,left+right)
        return max(left,right)+1 #左分支+右分支+根

lc 110【剑指 55-2】:平衡二叉树
https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/
提示:
树中的节点数在范围 [0, 5000] 内
-10^4 <= Node.val <= 10^4

#DFS
#后序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if not root:return True
        self.res=True
        self.postorder(root)
        return self.res
    def postorder(self,node):
        if not node:return 0
        left=self.postorder(node.left)
        right=self.postorder(node.right)
        if abs(right-left)>1:self.res=False
        return max(left,right)+1

lc 111 :二叉树的最小深度
https://leetcode.cn/problems/minimum-depth-of-binary-tree/
提示:
树中节点数的范围在 [0, 10^5] 内
-1000 <= Node.val <= 1000
注:最小深度是从根节点到最近叶子节点的最短路径上的节点数量

#BFS
#层序
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:return 0
        #
        queue=deque()
        queue.append(root)
        level=0
        while queue:
            level+=1
            for i in range(len(queue)):
                curr=queue.popleft()
                #key
                if not curr.left and not curr.right:
                    return level
                以上是关于日常系列LeetCode《16·二叉树1》的主要内容,如果未能解决你的问题,请参考以下文章

日常系列LeetCode《17·二叉树2》

Leecode 222. 完全二叉树的节点个数——Leecode日常刷题系列

Leecode 222. 完全二叉树的节点个数——Leecode日常刷题系列

二分法万能模板Leecode 222. 完全二叉树的节点个数——Leecode日常刷题系列

[leetcode] 2049 统计最高分的节点数目 | dfs二叉树

LeetCode 2049统计最高分的节点数目[dfs 二叉树] HERODING的LeetCode之路