双递归
面试题 04.12. 求和路径
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {number} sum
* @return {number}
*/
// 双递归
/*
一个主递归函数,一个内部递归函数
*/
var pathSum = function(root, sum) {
if (root == null) return 0;
/* 这里倒着减数字 */
const helper = (root, sum) => {
if (root == null) return 0;
if (sum == root.val) {
return 1 + helper(root.left, sum - root.val) + helper(root.right, sum - root.val);
}
return helper(root.left, sum - root.val) + helper(root.right, sum - root.val);
}
return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
};
563. 二叉树的坡度
/**
* 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 findTilt = function(root) {
if (root == null) return 0;
let res = 0;
const dfs = (root) => {
if (root == null) return 0;
const left = dfs(root.left);
const right = dfs(root.right);
res += Math.abs(right - left);
return right + left + root.val;
}
dfs(root)
return res;
};
129. 求根节点到叶节点数字之和
/**
* 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 sumNumbers = function(root) {
if (root == null) return 0;
let path = [];
const DFS = (root, sum) => {
if (root == null) return;
if (root.left == null && root.right == null) {
sum = sum * 10 + root.val;
path.push(sum);
}
sum = sum * 10 + root.val;
DFS(root.left, sum);
DFS(root.right, sum);
}
DFS(root, 0);
return path.reduce((prev, next) => {
return prev + next;
}, 0);
};
1448. 统计二叉树中好节点的数目
/**
* 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 goodNodes = function(root) {
if (root == null) return 0;
/* 因为根节点也是好节点 */
let res = 0;
const dfs = (root, max) => {
if (root == null) return;
if (root.val >= max) {
res += 1;
max = root.val;
}
dfs(root.left, max);
dfs(root.right, max);
}
dfs(root, Number.MIN_SAFE_INTEGER);
return res;
};
1022. 从根到叶的二进制数之和
/**
* 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 sumRootToLeaf = function(root) {
if (root == null) return 0;
let res = 0;
const dfs = (root, path) => {
if (root == null) return;
/* 添加值到路径里去 */
path.push(root.val);
if (root.left == null && root.right == null) {
/* 处理叶子结点 */
const num = path.join('');/* 生成二进制 */
res += parseInt(num, 2); /* 二进制转换为10进制 */
}
dfs(root.left, path);
dfs(root.right, path);
/* 回溯 */
path.pop();
};
dfs(root, [])
return res;
};
814. 二叉树剪枝
/**
* 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 {TreeNode}
*/
/* 利用了虚拟节点的概念 */
var pruneTree = function(root) {
const dfs = (root) => {
if (root == null) return 0;
const l = dfs(root.left);
const r = dfs(root.right);
if (l == 0) root.left = null;
if (r == 0) root.right = null;
/* 加起来,如果是0 就会被剪掉 */
return root.val + l + r;
}
let ans = new TreeNode(-1);
ans.left = root;
dfs(ans);
return ans.left;
};
1325. 删除给定值的叶子节点
/**
* 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} target
* @return {TreeNode}
*/
var removeLeafNodes = function(root, target) {
const dfs = (root) => {
if (root == null) return null;
root.left = dfs(root.left);
root.right = dfs(root.right);
/* 找到叶子节点,并且值为target */
if (root.val == target && root.left == null && root.right == null) {
/* 剪掉 */
return null;
}
return root;
}
return dfs(root);
};
边界
783. 二叉搜索树节点最小距离
/**
* 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 minDiffInBST = function(root) {
const dfs = (root, lower, upper) => {
if (root == null) return upper - lower;
const left = dfs(root.left, lower, root.val);
const right = dfs(root.right, root.val, upper);
return Math.min(left, right);
}
return dfs(root, -Infinity, Infinity);
};
1026. 节点与其祖先之间的最大差值
/**
* 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 maxAncestorDiff = function(root) {
const dfs = (root, lower, upper) => {
if (root == null) return upper - lower;
/* 计算两边的差值 */
const left = dfs(root.left, Math.min(lower, root.val), Math.max(root.val, upper));
const right = dfs(root.right, Math.min(lower, root.val), Math.max(root.val, upper));
/* 返回最大的一个差值 */
return Math.max(left, right);
}
return dfs(root, root.val, root.val);
};
下面两个题目,是一样的
865. 具有所有最深节点的最小子树
/**
* 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 {TreeNode}
*/
var subtreeWithAllDeepest = function(root) {
if (root == null) return null;
const getDepth = (root) => {
if(root == null) return 0;
return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
}
const left = getDepth(root.left);
const right = getDepth(root.right);
if (left == right) {
/* 当左右子树深度相同的时候,就是我们要找的最深的子树 */
return root;
} else if (left > right) {
return subtreeWithAllDeepest(root.left);
} else if (left < right) {
return subtreeWithAllDeepest(root.right);
}
};
1123. 最深叶节点的最近公共祖先
/**
* 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 {TreeNode}
*/
var lcaDeepestLeaves = function(root) {
if (root == null) return null;
const getDepth = (root) => {
if (root == null) return 0;
return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
}
const left = getDepth(root.left);
const right = getDepth(root.right);
if (left == right) {
/* 如果深度相同,那么就是我们要找的那个子树 */
return root;
} else if (left > right) {
/* 左边深度高,那么就往左侧找 */
return lcaDeepestLeaves(root.left);
} else if (left < right) {
/* 右边深度高,那么就往右侧找 */
return lcaDeepestLeaves(root.right);
}
};