Suzy找到实习了吗Day 18 | 二叉树进行中:513 找树左下角的值,112 路径总和 ,106.从中序与后序遍历序列构造二叉树

513 找树左下角的值

solution

# 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
# 这个题有坑:最底层的最左边结点的值包含:1.最底层;2.最左边
# 1.最底层肯定是叶子节点,但是叶子节点不一定在最底层
# 2.最左边的不一定是父节点的左孩子
class Solution:
    def getheight(self,root):
        if root.left==None and root.right==None:
            return 1
        else:
            h1=0
            h2=0
            if root.left: h1=self.getheight(root.left)
            if root.right: h2=self.getheight(root.right)
            return 1+max(h1,h2)
    def traversal(self,node,cur_height,max_height,record):
        print(node.val,cur_height)
        if node.left==None and node.right==None and cur_height==max_height:
            record.append(node.val)
            return  
        else:
            cur=cur_height #这里也容易写错!!!
            if node.left:
                cur+=1
                self.traversal(node.left,cur,max_height,record)
                cur-=1
            if node.right:
                cur+=1
                self.traversal(node.right,cur,max_height,record)
                cur-=1
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        height=self.getheight(root)
        print(height)
        record=[]
        self.traversal(root,1,height,record)
        print(record)
        if record: return record.pop(0)
        else:
            if height==1: return root.val
            else:
                return None
        

注意1!!!

这个题有坑:最底层的最左边结点的值包含:1.最底层;2.最左边

  1. 最底层肯定是叶子节点,但是叶子节点不一定在最底层
  2. 最左边的不一定是父节点的左孩子

注意2!!!

cur=cur_height
第一次这里的bug卡了好久,cur应该设置为一个全局变量,临时做的+1或者-1传入函数中,因为需要在出口判断。

函数中的cur_height表示当前节点所处在的层数;
cur记录根节点的层数,cur+1作为它的孩子结点所在的层数属性传入。用来回溯的关键!!!

递归三部曲再背一遍!!!

参数!
出口!
前/中/后 序遍历,中所在的地方表示处理根节点,其实cur=cur_height那行可以看成我在处理根节点。

112 路径总和

solution(全部是我自己写的噢!!!没有看视频!!!)

class Solution:
    def traversal(self,root,targetSum,path,flag):
        if root: path.append(root.val)#这句话的位置很关键
        else:
            return
        if root.left==None and root.right==None and sum(path)==targetSum:
            flag[0]=True
            return
        if root.left:
            #path.append(root.left.val) 
            self.traversal(root.left,targetSum,path,flag)
            path.pop()
        if root.right:
            #path.append(root.right.val)
            self.traversal(root.right,targetSum,path,flag)
            path.pop()
        
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        path=[]
        flag=[False]
        self.traversal(root,targetSum,path,flag)
        return flag[0]

一定要注意第三行代码的位置不要放后面去了
因为传统都是先写出口再处理中序遍历(中左右),但是因为我们需要把叶子结点的值让仅考虑的因素里,所以需要先处理“中”。

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

思路(我看的视频,因为我连手写怎么做都忘记了)

  1. 后序数组为0,说明无二叉树,返回空节点
  2. 后序数组的最后一个元素作为节点元素
  3. 在中序数组中寻找切割点 -> 切割中序数组
  4. 切割后续数组
  5. 递归地处理左区间和有区间

solution

class Solution:
    def getindex(self,list,taget):
        for i in range(len(list)):
            if list[i]==taget:break
        return i
        
    def traversal(self,inorder,postorder):
        if postorder==[]: return None
        
        # 根节点
        rootval=postorder.pop() #这里不能写pop,因为下面有判断post是否只有一个结点,如果是就返回
        root=TreeNode(rootval,None,None)
        # 这里指特殊情况,不是出口
        #if len(postorder)==1: return root

        # 切了中序数组,得到了左,右
        rootindex=self.getindex(inorder,rootval)
        inorder_left=inorder[:rootindex]
        inorder_right=inorder[rootindex+1:]

        # 怎么切后续数组呢(我不会):用中序数组切割出来的左中序的长度
        postorder_left=postorder[:len(inorder_left)]
        postorder_right=postorder[len(inorder_left):]
        # 递归调用,构造子树
        root.left=self.traversal(inorder_left,postorder_left)
        root.right=self.traversal(inorder_right,postorder_right)
        return root

    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        return self.traversal(inorder,postorder)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值