【更新中】记录一下最近遇到的几个二叉树的题型(附好用的遍历模板)

本文介绍了二叉树的层序、垂直、锯齿形遍历算法,以及N叉树的层序遍历,并探讨了如何通过前序、中序和后序遍历构建二叉树,包括889、105、106题的具体解法。同时,涉及了最近公共祖先问题的解决方案。
摘要由CSDN通过智能技术生成

107. 二叉树的层序遍历 II

102. 二叉树的层序遍历

987. 二叉树的垂序遍历

103. 二叉树的锯齿形层序遍历

429. N 叉树的层序遍历

2583. 二叉树中的第 K 大层和

513. 找树左下角的值

以上题目可共用一个模板(dfs记录数的col和row),不同之处就是使用哈希表的时候调整一下key和value,n叉树的情况只需要用一个for循环来遍历每一个child来代替二叉树中的左右子树:

# 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 verticalTraversal(self, root: Optional[TreeNode]) -> List[List[int]]:
        dic=defaultdict(list)
        def dfs(node,row,col):
            if node is None:
                return
            dic[col].append((row,node.val))
            dfs(node.left,row+1,col-1)
            dfs(node.right,row+1,col+1)
        dfs(root,0,0)
        ans=[]
        for _,i in sorted(dic.items()):
            i.sort()
            ans.append([j for _,j in i])
        return ans

更新103题的写法,在模板基础上加入一个flag来判断深度是否是偶数:

# 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 zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        dic=defaultdict(list)
        def dfs(node,row,col):
            if node is None:
                return
            dic[row].append((col,node.val))
            dfs(node.left,row+1,col-1)
            dfs(node.right,row+1,col+1)
        dfs(root,0,0)
        ans=[]
        flag=0
        for _, j in sorted(dic.items()):
            res=[]
            if flag%2==0:
                for i in range(len(j)):
                    res.append(j[i][1])
            else:
                for i in range(len(j)-1,-1,-1):
                    res.append(j[i][1])
            flag+=1
            ans.append(res)
        return ans

145. 二叉树的后序遍历

144. 二叉树的前序遍历

94. 二叉树的中序遍历

二叉树的前中后序遍历虽然是很基础的算法,但是我看到了一个很有意思的解题思路,特此记录一下:

# 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]:
        """
        #方法一
        white,gray=0,1
        ans=[]
        stack=[(white,root)]
        while stack:
            color,node=stack.pop()
            if node is None:
                continue
            if color==white:
                stack.append((white,node.right))
                stack.append((gray,node))
                stack.append((white,node.left))
            else:
                ans.append(node.val)
        return ans
        """
        #方法二
        ans=[]
        def mid(node):
            if node is not None:
                mid(node.left)
                ans.append(node.val)
                mid(node.right)
        mid(root)
        return ans

236. 二叉树的最近公共祖先

解题思路,先判断两个节点是否处于同一深度,如果不是同一深度,则让更深的节点向上移动至同一深度,随后两节点一同向上移动,直到两节点的父节点是同一节点时停止,这样就找到了最近公共祖先:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def find_depth(self, root, node):
        if not root:
            return 0
        if root == node:
            return 1
        left_depth = self.find_depth(root.left, node)
        right_depth = self.find_depth(root.right, node)
        if left_depth > 0:
            return left_depth + 1
        elif right_depth > 0:
            return right_depth + 1
        else:
            return 0

    def find_parent(self, root, node):
        if not root or not node:
            return None
        if root.left == node or root.right == node:
            return root
        parent = self.find_parent(root.left, node)
        if not parent:
            parent = self.find_parent(root.right, node)
        return parent

    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        depth_p, depth_q = self.find_depth(root, p), self.find_depth(root, q)
        while depth_p > depth_q:
            p = self.find_parent(root, p)
            depth_p -= 1
        while depth_q > depth_p:
            q = self.find_parent(root, q)
            depth_q -= 1
        while q != p:
            p = self.find_parent(root, p)
            q = self.find_parent(root, q)
        return p

889. 根据前序和后序遍历构造二叉树

106. 从中序与后序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树

106和105可以构建出唯一一棵二叉树,而889能构建不止一棵。使用递归的时候注意细节,由于前序遍历的顺序是中左右,所以105题先递归左子树后右子树。而后序遍历顺序是左右中,106题需要先递归右子树,后左子树。因为确定根节点位置是根据前序遍历和后序遍历来确定的(分别使用了pop(0)和pop():

# 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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if not preorder or not inorder:
            return None

        root_val = preorder.pop(0)
        root = TreeNode(root_val)
        root_position = inorder.index(root_val)

        root.left = self.buildTree(preorder, inorder[:root_position])
        root.right = self.buildTree(preorder, inorder[root_position + 1:])

        return root

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值