代码随想录算法训练营0525| 513.找树左下角的值、112. 路径总和、113.路径总和ii、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树

到现在也无法自行写出二叉树的题…除了层序遍历,递归好容易错…

513.找树左下角的值

只能自发写出层序遍历,看见dfs就头疼,晕递归

# 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
from collections import deque
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 
        deque = collections.deque([root])
        res = []
        depth = 0

        while deque:
            level = []
            depth += 1 
            for i in range(len(deque)):
                cur = deque.popleft()
                level.append(cur.val)

                if cur.left:
                    deque.append(cur.left)
                if cur.right:
                    deque.append(cur.right)

            res.append(level)

        return res[depth-1][0]

递归容易错的是,在访问完左子树之后深度不回溯,这样会导致,访问完左子树访问右子树时,深度持续叠加,失去了深度的意义

# 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.max_depth = -1#深度不会小于0,因此随便定义一个负值作为初始值
        depth = 0
        self.res = 0
        self.get_left(root,depth)#输入输出
        return self.res

    def get_left(self,root,depth):
        if not root.left and not root.right:#到达叶子节点
            if depth > self.max_depth:
                self.max_depth = depth
                self.res = root.val
            return

        if root.left:
            depth += 1
            self.get_left(root.left,depth)#如果在这层找到了叶子节点会直接return,没找到才会继续下一次循环
            depth -= 1#因此需要将深度回溯到这个节点的父节点,而保持深度始终有意义

        if root.right:
            depth += 1
            self.get_left(root.right,depth)
            depth -= 1

前判断中间的点,在判断左右,前左右的顺序---->前序遍历

12. 路径总和

和257.求路径数、还有上面那道题一样的思路,前序遍历,线判断当前节点是否满足条件,满足则return 不满足则开找左右,同样找路的时候要做回溯。

卡哥还用了一个巧妙的思想是从根节点一个一个节点减下来,若差值==0,则证明找到了一条路。

# 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) -> bool:
        if not root:
            return False
        
        return self.find_target(root,targetSum-root.val)


    def find_target(self,root,count):#输入,当前节点+目前计数
        #对当前节点的判断
        if not root.left and not root.right:#是叶子节点
            if count==0:#满足和等于目标值
                return True
            else :#不满足
                return False                

        if root.left:
            count -= root.left.val
            if self.find_target(root.left,count):#有节点在前面的判断中返回了True
                return True
            count += root.left.val

        if root.right:
            count -= root.right.val
            if self.find_target(root.right,count):
                return True
            count += root.right.val      

        return False  

怎么好像有点开始上道了,但是单靠我自己似乎不太容易厘清逻辑

113.路径总和ii

深浅拷贝害我找了好久错误都不知道为什么

深拷贝:像这里用的这样,是copy当前path中存储的所有值,两种写法:path.copy()或者path[:]

浅拷贝:引用path存储的地址,那么这个值会随着path的改变而改变

所以如果要copy的对象在函数中始终在变化--->使用深拷贝,否则平常使用浅拷贝也可

# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        if not root:
            return root
        Spath = [root.val]
        self.result = []
        self.find_path(root,Spath,targetSum-root.val)
        return self.result


    def find_path(self,root,path,count):     
        if not root.left and not root.right:#这里只做判断,满足条件result就append
            if count==0:
                self.result.append(path.copy())#注意这里要用深拷贝-->copy副本,而不像之前一样
                return
            else: 
                return 
                

        if root.left:
            path.append(root.left.val)
            print(path)
            count -= root.left.val
            print(count)
            # if self.find_path(root.left,path,count):#这里不再需要对递归的结果判断后再return了,结果已在判断那一部分做完
            #     self.result.append(path)
            self.find_path(root.left,path,count)
            count += root.left.val
            path.pop()


        if root.right:
            path.append(root.right.val)
            print(path)
            count -= root.right.val
            # if self.find_path(root.right,path,count):
            #     self.result.append(path)
            self.find_path(root.right,path,count)
            count += root.right.val
            path.pop()

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

暂跳,似乎一般不会考我二叉树,二刷来补

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值