思路
找到最大深度的叶子节点即可
终止条件
找到叶子节点 时 比较深度
单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯
/**
* 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
};