94. 二叉树的中序遍历
/**
* 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 inorderTraversal = function(root) {
const res = []
function inorder(node) {
if (node == null) return;
inorder(node.left);
if (node.val) {
res.push(node.val);
}
inorder(node.right);
}
inorder(root);
return res;
};
173. 二叉搜索树迭代器
算法思路:
- 在构造器里面的时候,使用中序遍历,都把value放在数组里,然后,调用各个原型上的方法的时候,直接去操作数组就行了
/**
* 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
*/
var BSTIterator = function(root) {
this.arr = [];
this.index = 0;
this.inorder(root);
};
/**
* @return {number}
*/
BSTIterator.prototype.next = function() {
return this.arr[this.index++];
};
/**
* @return {boolean}
*/
BSTIterator.prototype.hasNext = function() {
return this.index < this.arr.length;
};
/* 中序遍历 */
BSTIterator.prototype.inorder = function(node) {
if (node == null) return;
this.inorder(node.left);
//zhu
if (node.val !== null) {
this.arr.push(node.val);
}
this.inorder(node.right);
};
/**
* Your BSTIterator object will be instantiated and called as such:
* var obj = new BSTIterator(root)
* var param_1 = obj.next()
* var param_2 = obj.hasNext()
*/
完全二叉树
222. 完全二叉树的节点个数
使用的BFS 广度优先遍历,来计算数量
/**
* 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 countNodes = function(root) {
if (root == null) return 0;
let arr = [root];
let res = 1;
while (arr.length) {
let node = arr.shift();
if (node.left) {
res++;
arr.push(node.left);
}
if (node.right) {
res++;
arr.push(node.right);
}
}
return res;
};
662. 二叉树最大宽度
/**
* 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 widthOfBinaryTree = function(root) {
if (root == null) return 0;
let res = 0;
let leftmost = 0;
let cur_deps = 0;
let steps = 0;
let queue = [[root, 0]];
while (queue.length) {
const len = queue.length;
for(let i = 0; i < len; i++) {
let [node, pos] = queue.shift();
if (node || node.val == 0) {
queue.push([node.left, pos * 2]);
queue.push([node.right, pos * 2 + 1]);
if (cur_deps !== steps) {
cur_deps = steps;
leftmost = pos;
}
res = Math.max(res, pos - leftmost + 1);
}
}
steps += 1;
}
return res;
};
919. 完全二叉树插入器
/**
* 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
*/
var CBTInserter = function(root) {
};
/**
* @param {number} val
* @return {number}
*/
CBTInserter.prototype.insert = function(val) {
};
/**
* @return {TreeNode}
*/
CBTInserter.prototype.get_root = function() {
};
/**
* Your CBTInserter object will be instantiated and called as such:
* var obj = new CBTInserter(root)
* var param_1 = obj.insert(val)
* var param_2 = obj.get_root()
*/
路径
124. 二叉树中的最大路径和
/**
* 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}
*/
// DFS 后序遍历
var maxPathSum = function(root) {
if (root == null) return 0;
let res = Number.MIN_SAFE_INTEGER;
const dfs = (node, val) => {
if (node == null) return 0;
const left = dfs(node.left);
const right = dfs(node.right);
/* 所有的路径加起来 */
const maxSum = left + node.val + right;
/* 获取最大值,也是最终的返回值 */
res = Math.max(maxSum, res);
/* 当前子树,能够对外提供的最大的值 */
let outputSum = node.val + Math.max(0, left, right);
return outputSum < 0 ? 0 : outputSum;
}
dfs(root);
return res;
};
113. 路径总和 II
路径的概念是:一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。这听起来真的不容易理解,力扣给的 demo 我也没搞懂,这里我自己画了几个图来给大家解释一下这个概念。
/**
* 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 {number[][]}
*/
// DFS + 回溯
var pathSum = function(root, targetSum) {
if (root == null) return [];
let res = [];
let path = [];
// DFS
const dfs = (node, sum, path) => {
/* 第一步肯定是要终止条件 */
if (node == null) return;
/* 添加路径 */
path.push(node.val);
/* 开始加数, 计算路径总和 */
sum += node.val;
// 先条件判断,找到叶子节点
if (node.left == null && node.right == null) {
if (targetSum == sum) {
res.push([...path]);
}
}
if (node.left) {
dfs(node.left, sum, path);
}
if (node.right) {
dfs(node.right, sum, path);
}
// 回溯
path.pop();
};
dfs(root, 0, path);
return res;
};
距离
863. 二叉树中所有距离为 K 的结点
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} target
* @param {number} k
* @return {number[]}
*/
var distanceK = function(root, target, k) {
const map = new Map();
const res = [];
/* map 记录所有节点的父节点, 目的就是为了能向自己的父元素去递归查找 */
function findParents(node) {
if (node.left) {
map.set(node.left.val, node);
findParents(node.left);
}
if (node.right) {
map.set(node.right.val, node);
findParents(node.right);
}
}
findParents(root);
function DFS (node, from, depth, k) {
if (!node) return;
if (depth === k) {
res.push(node.val);
return;
}
// 向左下边递归
if (node.left !== from) {
DFS(node.left, node, depth + 1, k);
}
/* 向右下边递归 */
if (node.right !== from) {
DFS(node.right, node, depth + 1, k);
}
/* 向父元素递归 */
if (map.get(node.val) !== from) {
DFS(map.get(node.val), node, depth + 1, k);
}
}
DFS(target, null, 0, k);
return res;
};
834. 树中距离之和
这个暂时占个坑
/**
* @param {number} n
* @param {number[][]} edges
* @return {number[]}
*/
let ans, sz, dp, graph;
const dfs = (u, f) => {
sz[u] = 1;
dp[u] = 0;
for (const v of graph[u]) {
if (v === f) {
continue;
}
dfs(v, u);
dp[u] += dp[v] + sz[v];
sz[u] += sz[v];
}
}
const dfs2 = (u, f) => {
ans[u] = dp[u];
for (const v of graph[u]) {
if (v === f) {
continue;
}
const pu = dp[u], pv = dp[v];
const su = sz[u], sv = sz[v];
dp[u] -= dp[v] + sz[v];
sz[u] -= sz[v];
dp[v] += dp[u] + sz[u];
sz[v] += sz[u];
dfs2(v, u);
dp[u] = pu, dp[v] = pv;
sz[u] = su, sz[v] = sv;
}
}
var sumOfDistancesInTree = function(n, edges) {
ans = new Array(n).fill(0);
sz = new Array(n).fill(0);
dp = new Array(n).fill(0);
graph = new Array(n).fill(0).map(v => []);
for (const [u, v] of edges) {
graph[u].push(v);
graph[v].push(u);
}
dfs(0, -1);
dfs2(0, -1);
return ans;
};