二叉树相关

本文介绍了如何使用自顶向下和自底向上策略求解二叉树的最大深度问题,以及这两种方法与前序遍历和后序遍历的关系。通过递归实现,探讨了代码结构与操作顺序对算法的影响。
摘要由CSDN通过智能技术生成

LeetCode 104、二叉树的最大深度

解决这个问题可以用自顶向下(top-down),自底向上(bottom-up)两种解法

自顶向下的思路:

  • 和前序遍历紧密关联(根->左->右)

  • 当前节点的情况依赖于其父节点的情况

  • 考虑完父节点,再考虑当前节点

每次向下递归,depth+1,设置self.ans=depth,并且不断比较更新这个值,得到最大深度

class Solution:
    #自顶向下
    def dfs(self,node,depth):
        self.ans =max(depth,self.ans)
        #递归终止条件
        if node is None:
            return
        self.dfs(node.left,depth+1)
        self.dfs(node.right,depth+1)
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        self.ans=0
        #递归入口
        self.dfs(root,0)
        return self.ans

自底向上的思路:

  • 和后序遍历紧密关联(左->右->根)

  • 当前节点的情况依赖于其所有子节点的情况

  • 考虑完所有子节点,再考虑当前节点

如图,我们把最底下的叶节点深度看成1,那么节点3深度我们可以有预见性地看成2,节点1的根节点深度看成3.

节点3,为4,5的根节点,所以节点3的深度为左右子子树深度中的较大值加1:depth=max(left.depth,right.depth)+1

class Solution:
    #自底向上
    def dfs(self,node):
        #递归终止
        if node is None:
            return 0
        #递归子问题
        left_depth =self.dfs(node.left)
        right_depth=self.dfs(node.right)
        return max(left_depth,right_depth)+1
    def maxDepth(self, root: Optional[TreeNode]) -> int:   
        #递归入口
        return self.dfs(root)

自顶向下:和前序遍历紧密关联(根->左->右)

自顶向下本质上是前序的深度搜索

前序:考虑当前节点在递归之前

 

#LeetCode144、二叉树的前序遍历
class Solution:
    def dfs(self,ans,node):
        if node is None:
            return
        ans.append(node.val)
        self.dfs(ans,node.left)
        self.dfs(ans,node.right)
#访问根的值->对左做递归->对右做递归
class Solution:
    #自顶向下
    def dfs(self,node,depth):
#更新高度
        self.ans =max(depth,self.ans)
        #递归终止条件
        if node is None:
            return
        self.dfs(node.left,depth+1)
        self.dfs(node.right,depth+1)
#更新高度->调用递归(左节点递归->右结点递归)

自底向上的思路:和后序遍历紧密关联(左->右->根)

自底向上本质上是后续的深度搜索,

后序:考虑当前节点在递归之后

#LeetCode145、二叉树的后序遍历
class Solution:
    def dfs(self,ans,node):
        if node is None:
            return
        self.dfs(ans,node.left)
        self.dfs(ans,node.right)
        ans.append(node.val)
#对左做递归->对右做递归->访问根结点 
class Solution:
    #自底向上
    def dfs(self,node):
        #递归终止
        if node is None:
            return 0
        #递归子问题
        left_depth =self.dfs(node.left)
        right_depth=self.dfs(node.right)
        return max(left_depth,right_depth)+1
调用递归(左节点递归->右结点递归)->#更新高度

这样的关联决定了代码结构;

LeetCode 226、翻转二叉树

class Solution:
    #自顶向下
    # def dfs(self,node):
    #     if node is None:
    #         return
    #     node.left,node.right =node.right,node.left
    #     self.dfs(node.left)
    #     self.dfs(node.right)
    # def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
    #     self.dfs(root)
    #     return root
    
    #自底向上
    def dfs(self,node):
        if node is None:
            return
        self.dfs(node.left)
        self.dfs(node.right)
        node.left,node.right = node.right,node.left
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        self.dfs(root)
        return root 
#对于根节点的操作顺序决定了自顶向下/自底向上

LeetCode 111 、二叉树的最小深度

class Solution:
    # 自顶向下
    def dfs(self,node,depth):
        #递归终止条件:找到叶子节点,更新答案
        if node.left is None and node.right is None:
            self.ans = min(self.ans,depth)
            return
        #递归子问题
        #若左节点存在,对其进行递归,深度+1
        if node.left:
                self.dfs(node.left,depth +1)
        #若右节点存在,对其进行递归,深度+1
        if node.right:
                self.dfs(node.right,depth+1)
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        self.ans =inf
        self.dfs(root,1)
        return self.ans

LeetCode112、路径总和

class Solution:
    def dfs(self,node,pathSum,targetSum):
        if node is None:
            return
        pathSum += node.val
        #递归终止
        if node.left is None and node.right is None and targetSum == pathSum:
            self.ans = True
            return
        self.dfs(node.left,pathSum,targetSum)
        self.dfs(node.right,pathSum,targetSum)
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if root is None:
            return False
        self.ans =False
        self.dfs(root,0,targetSum)
        return self.ans

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值