题目要求
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
思路
路径每到一个节点,只有3中选择:①停在当前节点。②走到左子节点。 ③走到右子节点。
走到子节点,又有三种选择,递归就是用来处理规模不一样的相同问题。
注意:不能走进一个分支又掉头。
定义递归函数
- dfs函数:返回当前子树能向父节点提供的最大路径和
maxSum
,①子树根节点,收益为root.val
②左子树收益root.val+dfs(root.left)
③右子树收益root.val + dfs(root.right)
- 当遍历到
root
节点时,返回0; - 如果遇到负数,像
null
一样放回0;
子树内部路径要包含根节点
- 每递归一个子树,都求一下当前子树内部的最大路径和,再从中比较出最大的。
- 子树内部最大路径和
innerMaxSum
= 左子树提供的最大路径和dfs(root.left)
+ 根节点root.val
+ 右子树提供的最大路径和dfs(root.right)
var maxPathMax = function(root){
// 最大路径和,Number.MIN_SAFE_INTEGER最小最安全的integer型数字
let maxSum = Number.MIN_SAFE_INTEGER;
// dfs 函数,递归求子最大路径和
const dfs = (root) => {
// 筛选root中的空节点
if(root == null){
return 0;
}
// 左子树最大路径和
const left = dfs(root.left);
// 左子树最大路径和
const right = dfs(root.right);
// 子树内部最大路径和 = 做子树 + 根节点 + 右子树
const innerMaxSum = left + root.val + right;
// 更新maxSum值
maxSum = Math.max(maxSum, innerMaxSum);
// 子树向外提供最大路径和
const outputMaxSum = root.val + Math.max(left, right);
// 返回时检查有没有负数
return outputMaxSum < 0 ? 0 : outputMaxSum;
};
dfs(root); // 入口
return maxSum;
}
二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思考:
根据题意已知,二维数组从左往右递增,从上往下递增,所以得出以下结论:
某列的某个数字,该数之上的数字,都比其小;
某行的某个数字,该数右侧的数字,都比其大;
所以,解题流程如下所示:
以二维数组左下角为原点,建立直角坐标轴。
若当前数字大于了查找数,查找往上移一位。
若当前数字小于了查找数,查找往右移一位。
var findNumberIn2DArray = function(matrix, target) {
// 设置边界
if(!matrix.length) return false;
// 初始化右下角设置坐标
let x = matrix.length - 1, y = 0;
// 当x轴大于等于0 && y轴小于二维数组长度
while(x >= 0 && y < matrix[0].length ){
// 如果当前值 大于 目标值
if(matrix[x][y] === target){
return true;
}else if(matrix[x][y] > target){
// x轴上移
x--;
}else{
y++;
}
}
return false;
};