代码随想录算法训练营day18|513.找树左下角的值、112. 路径总和 113.路径总和ii

513.找树左下角的值

题目链接/文章讲解/视频讲解:代码随想录

思路:首先要是最后一行,然后是最左边的值。

如果使用递归法,如何判断是最后一行呢,其实就是深度最大的叶子节点一定是最后一行。

如果对二叉树深度和高度还有点疑惑的话,请看:110.平衡二叉树 (opens new window)

所以要找深度最大的叶子节点。

那么如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。

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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return None
        que = deque()
        que.append(root)
        result = 0

        while que:
            size = len(que)
            for i in range(size):
                node = que.popleft()
                if i==0:
                    result = node.val 
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
        return result

2.递归法

递归三部曲:

1.确定递归函数的参数和返回值

本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。

def traversal(self,node,depth)

2.确定终止条件

当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。

if not node.left and not node.right:
    if depth>self.maxDepth:
        self.maxDepth = depth 
        self.result = node.val

3.确定单层递归的逻辑

在找最大深度的时候,递归的过程中依然要使用回溯

        #左
        if node.left:
            depth += 1
            self.traversal(node.left,depth)
            depth -= 1
        #右
        if node.right:
            depth += 1
            self.traversal(node.right,depth)
            depth -= 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 findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        self.maxDepth = float('-inf')
        self.result = None
        self.traversal(root,0)
        return self.result
        
    def traversal(self,node,depth):
        if not node.left and not node.right:
            if depth>self.maxDepth:
                self.maxDepth = depth 
                self.result = node.val  
        #左
        if node.left:
            depth += 1
            self.traversal(node.left,depth)
            depth -= 1
        #右
        if node.right:
            depth += 1
            self.traversal(node.right,depth)
            depth -= 1

112. 路径总和  113.路径总和ii

题目链接/文章讲解/视频讲解:代码随想录

112.路径总和

自己是效仿257. 二叉树的所有路径写的

# 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 hasPathSum(self, root: Optional[TreeNode], targetSum: int):
        path = []
        result = []
        if not root:
            return False
        self.pathSum(root,path,result)
        if targetSum in result:
            return True 
        else:
            return False


    def pathSum(self,node,path,result):
        #中
        path.append(node.val)
        if not node.left and not node.right:
            result.append(sum(path))
        #左
        if node.left:
            self.pathSum(node.left,path,result)
            path.pop()
        #右
        if node.right:
            self.pathSum(node.right,path,result)
            path.pop()

本题我们要找一条符合条件的路径,所以递归函数需要返回值,及时返回,

112.路径总和

图中可以看出,遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以用bool类型表示。

# 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 hasPathSum(self, root: Optional[TreeNode], targetSum: int):
        if not root:
            return False
        return self.traversal(root,targetSum-root.val)
        

    def traversal(self,cur,count):
        if not cur.left and not cur.right and count == 0:
            return True 
        if not cur.left and not cur.right and count != 0:
            return False
        
        if cur.left:
            count -= cur.left.val
            if self.traversal(cur.left,count):
                return True
            count += cur.left.val

        if cur.right:
            count -= cur.right.val
            if self.traversal(cur.right,count):
                return True
            count += cur.right.val
        return False

113.路径总和-ii(这道题要再复习)

# 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 __init__(self):
        self.result = []
        self.path = []

    def traversal(self, cur, count):
        if not cur.left and not cur.right and count == 0: # 遇到了叶子节点且找到了和为sum的路径
            self.result.append(self.path[:])
            return

        if not cur.left and not cur.right: # 遇到叶子节点而没有找到合适的边,直接返回
            return

        if cur.left: # 左 (空节点不遍历)
            self.path.append(cur.left.val)
            count -= cur.left.val
            self.traversal(cur.left, count) # 递归
            count += cur.left.val # 回溯
            self.path.pop() # 回溯

        if cur.right: #  右 (空节点不遍历)
            self.path.append(cur.right.val) 
            count -= cur.right.val
            self.traversal(cur.right, count) # 递归
            count += cur.right.val # 回溯
            self.path.pop() # 回溯

        return

    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        self.result.clear()
        self.path.clear()
        if not root:
            return self.result
        self.path.append(root.val) # 把根节点放进路径
        self.traversal(root, sum - root.val)
        return self.result 

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

题目链接/文章讲解/视频讲解:代码随想录

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

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

# 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, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if not postorder:
            return None
        #找到根节点
        root_val = postorder[-1]
        root = TreeNode(root_val)

        #找切割点
        sep_id = inorder.index(root_val)

        #中序切割
        in_left = inorder[:sep_id]
        in_right = inorder[sep_id+1:]

        #后序切割
        pos_left = postorder[:len(in_left)]
        pos_right = postorder[len(in_left):len(postorder)-1]

        #递归
        root.left = self.buildTree(in_left,pos_left)
        root.right = self.buildTree(in_right,pos_right)

        return root

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

思路跟106一样

# 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:
            return None 
        
        #找根节点
        root_val = preorder[0]
        root = TreeNode(root_val)

        #找分割值
        sep_id = inorder.index(root_val)

        #分割中序数组
        in_left = inorder[:sep_id]
        in_right = inorder[sep_id+1:]

        #分割前序数组
        pre_left = preorder[1:len(in_left)+1]
        pre_right = preorder[len(in_left)+1:]

        #递归
        root.left = self.buildTree(pre_left,in_left)
        root.right = self.buildTree(pre_right,in_right)

        return root

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值