day18|二叉树5

513.找树左下角的值

本题可以利用最简单的层序遍历,进行求解,在层序遍历的过程中,取最左侧的结点即可。
本题判断最后一行最靠左侧的结点:满足最后一行的最靠左侧

  • 前:中左右
  • 中:左中右 √ :因为需要使用左右节点即可,不需要对中间结点进行返回
  • 后:左右中
# 修改全局变量方式的递归;返回相应值的递归
maxDepth = 0
result = 0
def traversal(root,depth):
	# 确定终止条件,深度最大的叶子结点中最左侧的节点
	if root.left is null and root.right is null:
		if depth > maxdepth:
			maxdepth = depth
			result = root.val # 不断更新即可,
	if root.left:
		depth ++
		traversal(node.left,depth)
		depth-- # 回溯的过程
	if root.right:
		depth ++
		traversal(node.right,depth)
		depth-- # 回溯的过程
	# 没有中的处理逻辑,因为本题没有中结点的处理逻辑

反思:

  1. 注意遍历时候终止条件的确定,本题中在碰到叶子结点时触发相应的终止条件。
  2. 设置全局变量,递归改变的是全局变量的值。
# 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.maxDepth = -1
        self.result = -1
    def getLeft(self, node, depth):
        if not node:
            return 
        if not node.left and not node.right:
            if self.maxDepth < depth:
                self.maxDepth = depth
                self.result = node.val
        self.getLeft(node.left, depth+1)
        self.getLeft(node.right, depth+1)
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        self.getLeft(root,0)
        return self.result

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

B站讲解:

在这里插入图片描述

递归+回退: 每一步递归返回的都是布尔类型的值,当前路径中是否可能存在满足targetNum的值。回溯的过程存在于,当计算得到的值,不满足当前的条件时,返回该值即可。
思考: 不需要将每一个叶子结点都进行遍历,只需要找到一个叶子结点,然后找到该叶子结点是否符合要求即可。

class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        def isornot(root, targetsum) -> bool:
            if (not root.left) and (not root.right) and targetsum == 0:
                return True  # 遇到叶子节点,并且计数为0
            if (not root.left) and (not root.right):
                return False  # 遇到叶子节点,计数不为0
            if root.left:
                targetsum -= root.left.val  # 左节点
                if isornot(root.left, targetsum): return True  # 递归,处理左节点
                targetsum += root.left.val  # 回溯
            if root.right:
                targetsum -= root.right.val  # 右节点
                if isornot(root.right, targetsum): return True  # 递归,处理右节点
                targetsum += root.right.val  # 回溯
            return False
        if not root:
            return False  # 别忘记处理空treenode
        else:
            return isornot(root, targetSum - root.val)
# 路径总和II
# 注意本题中
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        # 修正全局变量的值,因而不需要进行返回值的求解
        # 在处理result的过程中需要注意
        result = []
        tmp = []
        def dfs(root, tmp, targetsum):
            # 当前节点,当前结点对应的targetSum
            if not root:
                return 
            tmp.append(root.val) # 子节点
            targetsum -= root.val
            if (not root.left) and (not root.right) and targetsum == 0:
                result.append(tmp.copy())
            else:
                if root.left:
                    dfs(root.left, tmp, targetsum)  # 递归,处理左节点
                    tmp.pop() # 运行完之后pop当前的值找到上一层结点
                if root.right:
                    dfs(root.right, tmp, targetsum) # 递归,处理右节点
                    tmp.pop()
        # 进行深度优先搜索
        dfs(root,tmp,targetSum)
        if not root:
            return []  # 别忘记处理空treenode
        else:
            return result

自己探索:

class Solution:
    ''' # 本人代码
    def __init__(self):
        self.flag = -1
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        # 递归法,后续遍历中左右
        # 利用result记录
        def traversal(node,value):
            if not node.left and not node.right and value == targetSum:
                # 如果找到一个路径之和等于目标值的,中左右的顺序
                self.flag = 1
            if node.left:
                traversal(node.left,value + node.left.val)
            if node.right:
                traversal(node.right,value + node.right.val)
        if not root:
            return False
        traversal(root, root.val)
        if self.flag == 1: return True
        else: return False

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

基础知识:
中序:左中右
后序:左右中
tips: 后序和前序不能唯一确定的二叉树,因为只能确定中,不能确定左右区间的分割点。而中序+后序&中序+前序都可以唯一确定一个二叉树
基本步骤:
利用递归的方法对该问题进行求解,每一层涉及到了相同的结构。

  1. 后序数组为0,空结点
  2. 后序书序的最后一个元素为结点元素
  3. 寻找中序数组的位置作为切割点
  4. 切割中序数组(注意统一区间的规则)
  5. 切割后序数组(注意统一区间的规则)
  6. 递归处理相应的左区间和右区间
# 后序+中序
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        if not postorder:
            return 
        val = postorder[-1]
        index_val = inorder.index(val)
        # 对前序和中序数组进行切割
        root = TreeNode(val)
        leftInorder,rightInorder = inorder[0:index_val] , inorder[index_val+1:]
        leftPostorder,rightPostorder = postorder[0:len(leftInorder)], postorder[len(leftInorder):len(postorder)-1]
        root.left = self.buildTree(leftInorder,leftPostorder)
        root.right = self.buildTree(rightInorder,rightPostorder)
        return root
# 前序+中序
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        if not preorder:
            return 
        val = preorder[0]
        index_val = inorder.index(val)
        # 对前序和中序数组进行切割
        root = TreeNode(val)
        leftInorder,rightInorder = inorder[0:index_val] , inorder[index_val+1:]
        leftpreorder,rightpreorder = preorder[1:len(leftInorder)+1], preorder[len(leftInorder)+1:len(preorder)]
        root.left = self.buildTree(leftpreorder,leftInorder)
        root.right = self.buildTree(rightpreorder,rightInorder)
        return root
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值