day21 找树左下角的值||路径总和1、2||从中序与后序遍历序列构造二叉树

思路

找到最大深度的叶子节点即可

终止条件

找到叶子节点 时 比较深度 

单层递归的逻辑 

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

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findBottomLeftValue = function(root) {
// 在树的最后一行找到最左边的值
//  如何判断最后一行 深度最大的叶子节点一定是最后一行
// 所以要找深度最大的叶子节点

// 确定终止条件 当遇到叶子节点的时候就需要统计一下最大深度了,
let maxDepth = -1
let result
const traversal = function(node,depth){
    if(node.left===null && node.right===null){
        if(depth>maxDepth){
            maxDepth=depth
            result=node.val
        }
    }
    if(node.left){
        depth++
        traversal(node.left,depth)
        depth--
    }
    if(node.right){
        depth++
        traversal(node.right,depth)
        depth--

    }
    return; 
}
traversal(root,0)
return result
};

思路

可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值

递归终止条件

如果最后 遍历到了叶子节点 count===0 说明找到了目标和

遍历到叶子节点 count不为0 则没找到

单层递归的逻辑

因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。

递归函数有返回值,如果递归函数返回true,说明找到了合适的路径,应该立即返回

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
// 如果要搜索其中一条符合路径,那么递归一定需要返回值

// 计数器如何统计这一条路径的和 可以用递减 让计数器sum初始为目标和 
// 然后每次减去路径上的值  第一次传时也得减 不然不对
let traversal = function(node,sum){
    if(!node.left&&!node.right&&sum===0) return true
if(!node.left&&!node.right)return false

if(node.left){
    sum -=node.left.val
    if(traversal(node.left,sum)) return true
    sum+=node.left.val
}
if(node.right){
    sum-=node.right.val
    if(traversal(node.right,sum)) return true
    sum+=node.right.val
}
return false
}
if(!root) return false//这种情况 不要漏掉
return traversal(root,targetSum-root.val)//必须得减 
};

问题

如果root 为null  直接返回false

调用函数时,传count时 先把根节点的值减掉  count减去遍历路径上每个节点的值

思路

递归函数没有返回值了,

把路径放入res时 用[...path]进行深拷贝

思路

如何根据两个顺序构造一个唯一的二叉树

以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来切后序数组。

一层一层切下去,每次后序数组最后一个元素就是节点元素。

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} inorder
 * @param {number[]} postorder
 * @return {TreeNode}
 */
var buildTree = function(inorder, postorder) {
if(!inorder.length)return null
const rootVal = postorder.pop()//从后序遍历的数组中获取中间节点的值,即数组最后一个值
// 获取中间节点在中序遍历中的下标
let rootIndex = inorder.indexOf(rootVal)

const root= new TreeNode(rootVal);//创建中间节点
// slice(start,end) 开始索引 结束索引 不包含该索引元素
root.left = buildTree(inorder.slice(0,rootIndex),postorder.slice(0,rootIndex))
root.right = buildTree(inorder.slice(rootIndex+1),postorder.slice(rootIndex))//后序数组 已经pop了一个   inorder中序数组 要跳过切割点 就+1
return root
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值