二叉树部分:

这篇博客深入探讨了二叉树的各种算法,包括递归和非递归方法计算二叉树深度、二叉搜索树的第k个节点查找、根据先序和中序序列重建二叉树、判断树的子结构以及寻找二叉树中和为特定值的路径。此外,还介绍了寻找二叉树中两个节点的最近公共祖先的高效算法。
摘要由CSDN通过智能技术生成

(一)二叉树的深度

递归(分治法):分为求左右两个子树深度的问题,然后合并结果。计算复杂度:o(n),空间复杂度:o(n)

    def TreeDepth(self , pRoot: TreeNode) -> int:
        # write code here
        if not pRoot:
            return 0
        left=pRoot.left
        right=pRoot.right
        return max(self.TreeDepth(left), self.TreeDepth(right))+1

DFS遍历:计算复杂度:o(n),空间复杂度:o(n)

    def TreeDepth(self , pRoot: TreeNode) -> int:
        # write code here
        if not pRoot: 
            return 0
        queue, res = [pRoot], 0
        while queue:
            for i in range(len(queue)):
                tmp=queue.pop(0)
                if tmp.left: 
                    queue.append(tmp.left)
                if tmp.right: 
                    queue.append(tmp.right)
            res += 1
        return res

(二)二叉搜索树的第k个节点

 

由于是二插搜索树,进行中序遍历可得到有序数组

    def KthNode(self , proot: TreeNode, k: int) -> int:
        # write code here
        res = []
        self.inOrder(proot, res)
        if not res or k > len(res) or k <= 0:
            return -1
        return res[k-1]
    def inOrder(self, root, res):
        if not root:
            return
        self.inOrder(root.left, res)
        res.append(root.val)
        self.inOrder(root.right, res)

(三)重建二叉树

 递归的解法:计算复杂度 O(n),空间复杂度 O(n)

    def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
        # write code here
        if not pre:
            return
        root=TreeNode(pre[0])
        idx=vin.index(pre[0])
        root.left=self.reConstructBinaryTree(pre[1:1+idx],vin[:idx])
        root.right=self.reConstructBinaryTree(pre[1+idx::],vin[idx+1::])
        return root

 (四)树的子结构

 递归的解法:计算复杂度o(MN),空间复杂度o(M)

    def HasSubtree(self , pRoot1: TreeNode, pRoot2: TreeNode) -> bool:
        # write code here
        if not pRoot1 or not pRoot2:
            return False
        return self.isSub(pRoot1,pRoot2) or self.HasSubtree(pRoot1.left,pRoot2) or 
               self.HasSubtree(pRoot1.right,pRoot2)
    def isSub(self,root1,root2):
        if not root2:
            return True
        if not root1:
            return False
        return root1.val == root2.val and self.isSub(root1.left,root2.left) and 
               self.isSub(root1.right,root2.right)

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

递归式的深度优先搜索解法

    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        # write code here
        results = []
        if root == None:
            return results
        self.sum = expectNumber
        self.DFS(root, results, [root.val])
        return results
    def DFS(self, root, results,path):
        if root.left == None and root.right == None and sum(path) == self.sum:
            results.append(path)
        if root.left != None:
            self.DFS(root.left, results,path+[root.left.val])
        if root.right !=None:
            self.DFS(root.right, results, path+[root.right.val])

直接遍历二叉树,满足题述条件则将以列表形式存储的路径值保存下来

    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        # write code here
        results = []
        if not root:
            return results
        queue=[root]
        paths=[[root.val]]
        while queue:
            for i in range(len(queue)):
                tmp=queue.pop(0)
                v=paths.pop(0)
                if tmp.left:
                    queue.append(tmp.left)
                    paths.append(v+[tmp.left.val])
                if tmp.right:
                    queue.append(tmp.right)
                    paths.append(v+[tmp.right.val])
                if not tmp.left and not tmp.right and sum(v)==expectNumber:
                    results.append(v)
        return results

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

 

巧妙的递归解法,满足时间复杂度的要求。较难

    def lowestCommonAncestor(self , root: TreeNode, o1: int, o2: int) -> int:
        # write code here
        def dfs(root, o1, o2):
            if not root:
                return None
            # 如果不是同一层的,那么在根上第一个出现的就是公共祖先
            if root.val == o1 or root.val == o2:
                return root
            left = dfs(root.left, o1, o2)
            right = dfs(root.right, o1, o2)
            # 如果在同一层出现的,那么必然left和right都有,那么就返回root(该层的根)就行了
            if not left:
                return right
            if not right:
                return left
            return root
        return dfs(root, o1, o2).val

同一类型的题:在二叉搜索树中找最近的公共祖先。判断条件,祖先的结点大小一定在两者之间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值