Leetcode刷题之——二叉树总结

本文详细讲解了二叉树的前序、中序、后序遍历算法,以及层序遍历、镜像、序列化与重构等高级技巧。深入探讨了如何合并二叉树、查找最近公共祖先、右视图和平衡搜索树的构建。此外,还涉及到了序列化和反序列化二叉树、转化有序数组为平衡搜索树等实用操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前序、中序、后序遍历

class Solution:
    def preorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        
        if not root: return
        result = []
        def preorder(x):
            if not x: return
            result.append(x.val)
            preorder(x.left)
            preorder(x.right)
        preorder(root)
        return result
import sys
sys.setrecursionlimit(100000)
class Solution:
    def inorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        
        if not root: return
        result = []
        def inorder(x):
            if not x: return
            
            inorder(x.left)
            result.append(x.val)
            inorder(x.right)
        inorder(root)
        return result
class Solution:
    def postorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        
        if not root: return
        result = []
        def postorder(x):
            if not x: return
            postorder(x.left)
            postorder(x.right)
            result.append(x.val)
        postorder(root)
        return result

二叉树的层序遍历

class Solution:
    def levelOrder(self , root: TreeNode) -> List[List[int]]:
        # write code here
        res = []
        tree_list = []
        if root == None:
            return res
        tree_list.append(root)
        while len(tree_list) > 0:
            level_number = len(tree_list)
            tmp = []
            for i in range(level_number):
                # 记录每一层的节点个数
                node = tree_list.pop(0)
                tmp.append(node.val)
                if node.left:
                    tree_list.append(node.left)
                if node.right:
                    tree_list.append(node.right)
            res.append(tmp)
        return res

按之字形打印二叉树

class Solution:
    def Print(self , pRoot: TreeNode) -> List[List[int]]:
        # write code here
        import collections
        

        if not pRoot: return []
        res, queue = [], collections.deque()
        queue.append(pRoot)
        count = 0
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
               
            count += 1
            if count%2!=0:
                res.append(tmp)
            else:
                res.append(tmp[::-1])
        return res

二叉树的最大深度

class Solution:
    def maxDepth(self , root: TreeNode) -> int:
        # write code here
  
        if not root: return 0
   
        return max(self.maxDepth(root.left),self.maxDepth(root.right)) + 1

二叉树中和为某一值的路径

class Solution:
    def hasPathSum(self , root: TreeNode, sum: int) -> bool:
        # write code here
        
        if not root:return False
        
        if not root.left and not root.right and sum-root.val == 0:
            return True
        return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right, sum-root.val)

二叉搜索树和双向链表

class Solution:
    head = None
    pre = None
    def Convert(self , pRootOfTree ):
        if not pRootOfTree:
            # 中序递归,叶子为空则返回
            return None       
        # 首先递归到最左最小值
        self.Convert(pRootOfTree.left) 
        # 找到最小值,初始化head与pre
        if not self.pre:       
            self.head = pRootOfTree
            self.pre = pRootOfTree
        # 当前节点与上一节点建立连接,将pre设置为当前值
        else:       
            self.pre.right = pRootOfTree
            pRootOfTree.left = self.pre
            self.pre = pRootOfTree
        self.Convert(pRootOfTree.right)
        return self.head

对称的二叉树

class Solution:
    def recursion(self, root1: TreeNode, root2: TreeNode):
        # 可以两个都为空
        if not root1 and not root2: 
            return True
        # 只有一个为空或者节点值不同,必定不对称
        if not root1 or not root2 or root1.val != root2.val:
            return False
        # 每层对应的节点进入递归
        return self.recursion(root1.left, root2.right) and self.recursion(root1.right, root2.left)

    def isSymmetrical(self , pRoot: TreeNode) -> bool:
        return self.recursion(pRoot, pRoot)

class Solution:
    def isSymmetrical(self , pRoot: TreeNode) -> bool:
        temp1 = []
        temp2 = []
        temp = pRoot
        def preorder(x):
            if not x: 
                return
            if not x.left or not x.right:
                temp1.append(-1)
            
            preorder(x.left)
            temp1.append(x.val)
            preorder(x.right)
        
        def order(x):
            if not x: 
                return
            if not x.left or not x.right:
                temp2.append(-1)
            order(x.right)
            temp2.append(x.val)
            order(x.left)
        preorder(pRoot)
        order(temp)
        print(temp1,temp2)
        return True if temp1==temp2 else False

合并二叉树
【已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替】

class Solution:
    def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
        # write code here
        
        if not t1: return t2
        if not t2: return t1
        
        head = TreeNode(t1.val + t2.val)
        head.left = self.mergeTrees(t1.left,t2.left)
        head.right = self.mergeTrees(t1.right, t2.right)
        return head

二叉树的镜像

class Solution:
    def Mirror(self , pRoot: TreeNode) -> TreeNode:
        # write code here
        if not pRoot: return
        head = TreeNode(pRoot.val)
        head.left = self.Mirror(pRoot.right)
        head.right = self.Mirror(pRoot.left)
        return head

判断是不是二叉搜索树

class Solution:
    def isValidBST(self , root: TreeNode) -> bool:
        # write code here
        temp = []
        if not root:return
        def inorder(x):
            if not x:return
            
            inorder(x.left)
            
            temp.append(x.val)
            inorder(x.right)
        inorder(root)
        return temp == sorted(temp)

判断是不是完全二叉树

class Solution:
    def isCompleteTree(self , root: TreeNode) -> bool:
        # write code here
        nodes = [(root, 1)]
        i = 0
        while i < len(nodes):
            node, v = nodes[i]
            i += 1                                    # 计数当前是第几个节点
            if node:
                nodes.append((node.left, 2*v))        # 继续为左子节点编号
                nodes.append((node.right, 2*v+1))     # 继续为右子节点编号
        return nodes[-1][1] == i

判断是不是平衡二叉树

class Solution:
    def IsBalanced_Solution(self , pRoot: TreeNode) -> bool:
        # write code here
        if not pRoot: return True
        
        def depth(x):
            if not x: return 0
            return max(depth(x.left),depth(x.right)) + 1
        
        return abs(depth(pRoot.left)-depth(pRoot.right))<=1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)

二叉搜索树的最近公共祖先

class Solution:
    def lowestCommonAncestor(self , root: TreeNode, p: int, q: int) -> int:
        # 空树找不到公共祖先
        if not root:
            return -1
        # pq在该节点两边说明这就是最近公共祖先
        if (p >= root.val and q <= root.val) or (p <= root.val and q >= root.val):
            return root.val
        # pq都在该节点的左边
        elif p <= root.val and q <= root.val:
            # 进入左子树
            return self.lowestCommonAncestor(root.left, p, q)
        #pq都在该节点的右边
        else:
            # 进入右子树
            return self.lowestCommonAncestor(root.right, p, q)

在二叉树中找到两个节点的最近公共祖先

class Solution:
    def lowestCommonAncestor(self , root: TreeNode, o1: int, o2: int) -> int:
        # 该子树没找到,返回-1
        if not root: 
            return -1
        # 该节点是其中某一个节点
        if root.val == o1 or root.val == o2: 
            return root.val
        # 左子树寻找公共祖先
        left = self.lowestCommonAncestor(root.left, o1, o2) 
        # 右子树寻找公共祖先
        right = self.lowestCommonAncestor(root.right, o1, o2) 
        # 左子树为没找到,则在右子树中
        if left == -1: 
            return right
        # 右子树没找到,则在左子树中
        if right == -1: 
            return left
        # 否则是当前节点
        return root.val 

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """

        if not root:return False

        if root == p or root == q:
            return root

        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)

        if not left:
            return right
        if not right:
            return left
        
        return root
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """

         # 如果当前节点的值 node.val 大于 p 和 q 的值,那证明 p 和 q 在 node 的左子树中
        if root.val > p.val and root.val > q.val:
            # 遍历左子树
            return self.lowestCommonAncestor(root.left, p, q)
        # 如果当前节点的值 node.val 小于 p 和 q 的值,那证明 p 和 q 在 node 的右子树中
        if root.val < p.val and root.val < q.val:
            # 遍历右子树
            return self.lowestCommonAncestor(root.right, p, q)
        # 如果当前节点的值 node.val 在 [p, q] 之间,那 node 就是最近公共祖先。
        return root

序列化二叉树

class Solution:
    str1 = []
    def Serialize(self, root):
        # write code here
        if root == None:
            self.str1.append("#")
            return self.str1
        self.str1.append(str(root.val))
        self.Serialize(root.left)
        self.Serialize(root.right)
        return self.str1
    start=-1
    def Deserialize(self, s):
        # write code here
        self.start=self.start+1;
        if self.start>=len(s) or s[self.start]=="#" or s==None :return ;
        cur=TreeNode(int(s[self.start]))
        cur.left=self.Deserialize(s)
        cur.right=self.Deserialize(s)
        return cur

重建二叉树
【给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。】

class Solution:
    def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
        n = len(pre)
        m = len(vin)
        # 每个遍历都不能为0
        if n == 0 or m == 0: 
            return None
        # 构建根节点
        root = TreeNode(pre[0]) 
        for i in range(len(vin)):
            # 找到中序遍历中的前序第一个元素
            if pre[0] == vin[i]: 
                # 左子树的前序遍历
                leftpre = pre[1:i+1] 
                # 左子树的中序遍历
                leftvin = vin[:i] 
                # 构建左子树
                root.left = self.reConstructBinaryTree(leftpre, leftvin) 
                # 右子树的前序遍历
                rightpre = pre[i+1:] 
                # 右子树的中序遍历
                rightvin = vin[i+1:] 
                # 构建右子树
                root.right = self.reConstructBinaryTree(rightpre, rightvin) 
                break
        return root
class Solution:
    def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
        # write code here
        if not pre or not vin:
            return None
        #构造根节点,寻找左右子树的分界线
        root = TreeNode(pre[0])
        n = vin.index(pre[0])
        #构造左右子树,递归调用
        root.left = self.reConstructBinaryTree(pre[1:n + 1], vin[:n])
        root.right = self.reConstructBinaryTree(pre[n + 1:], vin[n + 1:])
        #返回根节点
        return root

输出二叉树的右视图

【请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图】

class Solution:
    def solve(self , xianxu , zhongxu ):
        # write code here
        result = []
        def dfs(p, i, level):
            if not p:
                return
            if level >= len(result):
                result.append(p[0])
            else:
                result[level] = p[0]
 
            tmp = i.index(p[0]) 
            dfs(p[1:tmp+1], i[0:tmp] , level+1)
            dfs(p[tmp+1:], i[tmp+1:], level+1)
 
        dfs(xianxu, zhongxu, 0)
        return result

108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        
        
        def helper(left, right):
            if left > right:
                return None

            # 总是选择中间位置左边的数字作为根节点
            mid = (left + right) // 2

            root = TreeNode(nums[mid])
            root.left = helper(left, mid - 1)
            root.right = helper(mid + 1, right)
            return root

        return helper(0, len(nums) - 1)

二叉树的右视图
【给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。】

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        # 分别取左子树和右子树的右视图
        left = self.rightSideView(root.left)
        right = self.rightSideView(root.right)
        # 如果右子树的右视图大,则返回[root.val] + right
        if len(left) <= len(right):
            return [root.val] + right
        # 否则,返回左子树左视图多余的部分加右子树右视图加root.val
        else:
            return [root.val] + right + left[len(right):]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值