1530. 好叶子节点对的数量
/**
* 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} distance
* @return {number}
*/
/* 后序遍历 */
var countPairs = function(root, distance) {
if (root == null) return 0;
let res = 0;
const dfs = (root) => {
if (root == null) return [];
/* 叶子节点 */
if (root.left == null && root.right == null) return [0];
const left = dfs(root.left).map(i => i + 1);
const right = dfs(root.right).map(i => i + 1);
/* 计算最短路径 */
for (const l of left) {
for (const r of right) {
if (l + r <= distance) res++;
}
}
return [...left, ...right];
}
dfs(root);
return res;
};
剑指 Offer 55 - I. 二叉树的深度
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
/* 后序遍历 */
var maxDepth = function(root) {
if (root == null) return 0;
const dfs = (root) => {
if (root == null) return 0;
const left = dfs(root.left);
const right = dfs(root.right);
return Math.max(left, right) + 1;
};
return dfs(root);
};
101. 对称二叉树
/**
* 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 {boolean}
*/
var isSymmetric = function(root) {
const check = (leftNode, rightNode) => {
if (leftNode == null && rightNode == null) return true;
if (leftNode == null || rightNode == null) return false;
return leftNode.val == rightNode.val && check(leftNode.left, rightNode.right) && check(leftNode.right, rightNode.left);
};
return check(root, root);
};
226. 翻转二叉树
简单: 226. 翻转二叉树
/**
* 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 invertTree = function(root) {
if (root == null) return null;
const left = invertTree(root.left);
const right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
};
543. 二叉树的直径
/**
* 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 diameterOfBinaryTree = function(root) {
if (root == null) return null;
let res = 0;
const dfs = (root) => {
if (root == null) return 0;
const left = dfs(root.left);
const right = dfs(root.right);
/* 取最大值 */
res = Math.max(res, left+right);
return Math.max(left, right) + 1;
}
dfs(root);
return res;
};
971. 翻转二叉树以匹配先序遍历
/**
* 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[]} voyage
* @return {number[]}
*/
var flipMatchVoyage = function(root, voyage) {
if (root == null) return [-1];
if (root.val !== voyage[0]) return [-1];
let res = [];
let i = 0;
const dfs = (root) => {
if (root == null) return;
i++;
/* 如果左树匹配 */
if (root.left && root.left.val == voyage[i]) {
dfs(root.left);
}
if (root.right && root.right.val == voyage[i]) {
dfs(root.right);
/* 右树完成之后,需要看看现在 pos 所在的值是否可以匹配左树,即是否先走右树再走左树,成立即当前的 root 节点就是需要进行翻转的节点 */
if (root.left && root.left.val == voyage[i]) {
res.push(root.val);
dfs(root.left);
}
}
}
dfs(root);
if (i < voyage.length) return [-1];
return res;
};
面试题 04.06. 后继者
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @return {TreeNode}
*/
/* 中序遍历 */
var inorderSuccessor = function(root, p) {
if(root == null) {
return null;
}
const arr = [];
let res = 0;
const dfs = (root) => {
if(root == null) return;
dfs(root.left);
arr.push(root);
if(root == p) {
res = arr.length;
}
dfs(root.right);
}
dfs(root);
return arr[res];
};
144. 二叉树的前序遍历
/**
* 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 preorderTraversal = function(root) {
if (root == null) return [];
const res = [];
const dfs = (root) => {
if (root == null) return;
res.push(root.val);
root.left && dfs(root.left);
root.right && dfs(root.right);
}
dfs(root);
return res;
};
230. 二叉搜索树中第K小的元素
/**
* 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} k
* @return {number}
*/
/* 中序遍历 */
var kthSmallest = function(root, k) {
if (root == null) return null;
const res = [];
const dfs = (root) => {
if (root == null) return;
dfs(root.left);
res.push(root.val);
dfs(root.right);
}
dfs(root);
return res[k - 1];
};
145. 二叉树的后序遍历
/**
* 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 postorderTraversal = function(root) {
if (root == null) return [];
const res = [];
const dfs = (root) => {
if (root == null) return;
dfs(root.left);
dfs(root.right);
res.push(root.val);
}
dfs(root);
return res;
};
102. 二叉树的层序遍历
/**
* 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 levelOrder = function(root) {
if (root == null) return [];
const res = [];
const queue = [root];
while (queue.length) {
/* 记录当前层的节点数 */
let length = queue.length;
/* 存放每一层的节点 */
let currentArr = [];
for (let index = 0; index < length; index++) {
/* 这里注意要用shift, 因为下面是push, 所以要取头部的 */
const node = queue.shift();
currentArr.push(node.val);
/* 存放下一层的节点 */
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
res.push(currentArr);
}
return res;
};
236. 二叉树的最近公共祖先
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
if(root == null) return null;
const dfs = (root) => {
/* 确定递归终止条件 */
if (root == null) {return null;}
/* 这是其中一种情况, 如果root 等于其中某一个,那么,root就是要找到的最近的公共祖先 */
if(root == p || root == q) {
return root;
}
const left = dfs(root.left);
const right = dfs(root.right);
if(left && right) {
/* 当这两个同时不为空,那么p,q 肯定就是在root的两侧,那么root就是我们要找的节点 */
return root;
}
if (left == null) {
return right;
}
return left;
}
return dfs(root);
};
103. 二叉树的锯齿形层序遍历
/**
* 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 zigzagLevelOrder = function(root) {
if (root == null) return [];
const queue = [root];
let res = [];
/* 设置一个开关 */
let b = true;
while (queue.length) {
let length = queue.length;
let curArr = [];
for (let index = 0; index < length; index++) {
const node = queue.shift();
curArr.push(node.val);
/* 新的一层 */
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
/* 进行反转 */
if(!b) {
curArr = curArr.reverse();
}
b = !b;
res.push(curArr);
}
return res;
};
107. 二叉树的层序遍历 II
/**
* 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 levelOrderBottom = function(root) {
if (root == null) return [];
const queue = [root];
const res = [];
while(queue.length) {
const curArr = [];
const length = queue.length;
for (let index = 0; index < length; index++) {
const node = queue.shift();
curArr.push(node.val);
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
res.push(curArr);
}
return res.reverse();
};
701. 二叉搜索树中的插入操作
/**
* 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} val
* @return {TreeNode}
*/
var insertIntoBST = function(root, val) {
if (root == null) {
return new TreeNode(val);
}
if (root.val >= val) {
/* 如果当前的节点大于等于要插入的节点,那么就插入左子树 */
root.left = insertIntoBST(root.left, val);
} else {
root.right = insertIntoBST(root.right, val);
}
return root;
};
108. 将有序数组转换为二叉搜索树
/**
* 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[]} nums
* @return {TreeNode}
*/
var sortedArrayToBST = function(nums) {
if (nums.length === 0) return null;
const dfs = (nums, left, right) => {
// 条件限制
if (left > right) return null;
// 找到中点
const mid = Math.floor(left + (right - left) / 2);
const root = new TreeNode(nums[mid]);
// 左子树
root.left = dfs(nums, left, mid - 1);
// 右子树
root.right = dfs(nums, mid + 1, right);
return root;
}
return dfs(nums, 0, nums.length - 1);
};
1382. 将二叉搜索树变平衡
/**
* 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}
*/
/*
上一个题目,是一个有序数组转化为平衡二叉树
思路:
1, 先把BST 中序遍历,生成一个有序数组
2, 再把这个有序数组转化为平衡BST二叉树
*/
var balanceBST = function(root) {
if (root == null) return null;
const arr = [];
const inorder = (root) => {
if (root == null) return;
inorder(root.left);
arr.push(root.val);
inorder(root.right);
}
inorder(root);
const buildDfs = (arr, left, right) => {
if (left > right) return null;
// zhong
const mid = Math.floor(left + (right - left) / 2);
const root = new TreeNode(arr[mid]);
root.left = buildDfs(arr, left, mid - 1);
root.right = buildDfs(arr, mid + 1, right);
return root;
}
return buildDfs(arr, 0, arr.length - 1);
};
100. 相同的树
/**
* 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} p
* @param {TreeNode} q
* @return {boolean}
*/
var isSameTree = function(p, q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val !== q.val) {
return false;
} else {
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
};
111. 二叉树的最小深度
/**
* 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}
*/
/* 这个使用BFS 更好理解 */
var minDepth = function(root) {
if (root == null) return 0;
const queue = [root];
let depth = 1;
while(queue.length) {
const length = queue.length;
for (let index = 0; index < length; index++) {
const node = queue.shift();
if (node.left == null && node.right == null) {
return depth;
}
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right)
}
}
depth += 1;
}
return depth;
};
112. 路径总和
/**
* 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) {
if(root == null) {
return false;
}
if (root.left == null && root.right == null) {
return root.val === targetSum;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
};
235. 二叉搜索树的最近公共祖先
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
if (root == null) return null;
const dfs = (root) => {
if (root == null) {
return null;
}
/* 这是其中一种情况, 如果root 等于其中某一个,那么,root就是要找到的最近的公共祖先 */
if (root.val == p.val || root.val == q.val) {
return root;
}
const left = dfs(root.left);
const right = dfs(root.right);
if (left && right) {
return root;
}
if (left == null) {
return right;
}
return left;
}
return dfs(root);
};
257. 二叉树的所有路径
/**
* 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 {string[]}
*/
var binaryTreePaths = function(root) {
if (root == null) return [];
const res = [];
const dfs = (root, arr) => {
if (root == null) return;
arr.push(root.val);
if (root.left == null && root.right == null) {
const str = arr.join('->');
res.push(str);
}
dfs(root.left, arr);
dfs(root.right, arr);
/* 回溯 */
arr.pop();
}
dfs(root, []);
return res;
};
404. 左叶子之和
简单
/**
* 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 sumOfLeftLeaves = function(root) {
if (root == null) return 0;
let num = 0;
const dfs = (root) => {
if (root == null) return;
if (root.left !== null && root.left.left == null && root.left.right == null) {
num = num + root.left.val;
}
dfs(root.left);
dfs(root.right);
}
dfs(root);
return num;
};
501. 二叉搜索树中的众数
/**
* 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 findMode = function(root) {
if (root == null) return [];
let res = [];
let pre; /* 当前数字 */
let preNum; /* 当前数字的数量 */
let max = 0;
const dfs = (root) => {
if(root == null) return;
if (root.left) dfs(root.left);
/* 处理判断条件 */
if (root.val == pre) {
preNum++;
} else {
pre = root.val;
preNum = 1;
}
if (preNum > max) {
max = preNum;
/* 替换为新的众数 */
res = [root.val];
} else if (preNum == max) {
res.push(root.val);
}
if (root.right) dfs(root.right);
}
dfs(root);
return res;
};
530. 二叉搜索树的最小绝对差
/**
* 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 getMinimumDifference = function(root) {
let min = Number.MAX_SAFE_INTEGER;
let pre = -1;
const dfs = (root) => {
if (root == null) return;
if(root.left) dfs(root.left);
/* 逻辑 */
if (pre == -1) {
pre = root.val;
} else {
min = Math.min(root.val - pre, min);
pre = root.val;
}
if(root.right) dfs(root.right);
}
dfs(root);
return min;
};
572. 另一棵树的子树
/**
* 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 {TreeNode} subRoot
* @return {boolean}
*/
var isSubtree = function(root, subRoot) {
let bool = true
let res = false
let subnode = subRoot
function tra(n1, n2) {
if (n1 && n2) {
if (n1.val === n2.val) {
tra(n1.left, n2.left)
tra(n1.right, n2.right)
} else {
bool = false
}
} else {
if ((!n2 && !n1)) {
return ;
} else {
bool = false
}
}
}
function traverse(node) {
// 如果已经找到相同子树了(res === true)就直接返回不再递归了
// 防止重复的叶子,导致res置false
if (!node || res) {
return ;
}
if (node.val === subnode.val) {
// 每次准备dfs子树时,先将标志置true
// 因为树中可能有重复val的叶子
bool = true
tra(node, subnode)
res = bool
}
traverse(node.left)
traverse(node.right)
}
traverse(root)
return res
};
606. 根据二叉树创建字符串
简单
/**
* 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 {string}
*/
var tree2str = function(root) {
if (root == null) return '';
const dfs = (root) => {
if(root == null) return '';
/* 找到叶子节点 */
if (root.left == null && root.right == null) {
return `${root.val}`;
}
let left, right;
if(root.left && !root.right) {
left = `(${dfs(root.left)})`;
right = '';
} else {
left = root.left ? `(${dfs(root.left)})` : '()';
right = `(${dfs(root.right)})`;
}
return `${root.val}${left}${right}`;
}
return dfs(root);
};