144. 二叉树的前序遍历
/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
if(!root) return;
res.push(root.val);
dfs(root.left);
dfs(root.right);
}
dfs(root);
return res;
};
94. 二叉树的中序遍历
/**
* @param {TreeNode} root
* @return {number[]}
*/
var inorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
if(!root) return;
dfs(root.left);
res.push(root.val);
dfs(root.right);
}
dfs(root);
return res;
};
145. 二叉树的后序遍历
/**
* @param {TreeNode} root
* @return {number[]}
*/
var postorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
if(!root) return;
dfs(root.left);
dfs(root.right);
res.push(root.val);
}
dfs(root);
return res;
};
剑指 Offer 07. 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function(preorder, inorder) {
if (!preorder.length || !inorder.length) {
return null;
}
const rootVal = preorder[0];
const node = new TreeNode(rootVal);
let i = inorder.indexOf(rootVal);
node.left = buildTree(preorder.slice(1, i + 1), inorder.slice(0, i));
node.right = buildTree(preorder.slice(i + 1), inorder.slice(i + 1));
return node;
};
102. 二叉树的层序遍历
即逐层地,从左到右访问所有节点
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if(!root) return [];
let res = [];
let queue = [];
queue.push(root);
while(queue.length) {
let len = queue.length;
let cur = [];
while(len--) {
let temp = queue.shift();
cur.push(temp.val);
if(temp.left) queue.push(temp.left);
if(temp.right) queue.push(temp.right);
}
res.push(cur);
}
return res;
}
103. 二叉树的锯齿形层序遍历
即先从左往右,再从右往左进行下一层遍历
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var zigzagLevelOrder = function (root) {
if(!root) return [];
let res = [];
let queue = [];
queue.push(root);
while(queue.length) {
let len = queue.length;
let cur = [];
while(len--) {
let temp = queue.shift();
cur.push(temp.val);
if(temp.left) queue.push(temp.left);
if(temp.right) queue.push(temp.right);
}
res.length % 2 === 0 ? res.push(cur) : res.push(cur.reverse());
}
return res;
};
589. N 叉树的前序遍历
输入: root = [1,null,3,2,4,null,5,6]
输出: [1,3,5,6,2,4]
/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node|null} root
* @return {number[]}
*/
var preorder = function(root) {
let res = [];
const dfs = (root) => {
if(!root) return;
res.push(root.val);
for(let i = 0; i < root.children.length; i++) {
dfs(root.children[i]);
}
}
dfs(root);
return res;
};
590. N 叉树的后序遍历
输入: root = [1,null,3,2,4,null,5,6]
输出: [5,6,3,2,4,1]
/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node|null} root
* @return {number[]}
*/
var postorder = function(root) {
let res = [];
const dfs = (root) => {
if(!root) return;
for(let i = 0; i < root.children.length; i++) {
dfs(root.children[i]);
}
res.push(root.val);
}
dfs(root);
return res;
};
101. 对称二叉树
使用递归从上往下依次比较,并返回比较结果。
给定一个二叉树,检查它是否是镜像对称的。
二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(!root) return true;
const dfs = (left, right) => {
if(!left && !right) return true;
if(!left || !right || right.val !== left.val) return false;
return dfs(left.left, right.right) && dfs(left.right, right.left);
}
return dfs(root.left, root.right);
};
226. 翻转二叉树
使用递归从上往下依次翻转,并返回翻转的结果。
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
const dfs = (root) => {
if(!root) return root;
let temp = root.left;
root.left = root.right;
root.right = temp;
dfs(root.left);
dfs(root.right);
return root;
}
return dfs(root);
};
617. 合并二叉树
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
/**
* 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} root1
* @param {TreeNode} root2
* @return {TreeNode}
*/
var mergeTrees = function(root1, root2) {
const dfs = (root1, root2) => {
if(root1 === null && root2) return root2;
if((root1 && root2 === null) || (root1 === null && root2 === null)) return root1;
let root = new TreeNode(root1.val + root2.val);
root.left = dfs(root1.left, root2.left);
root.right = dfs(root1.right, root2.right);
return root;
}
return dfs(root1, root2);
};
110. 平衡二叉树
平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
输入: root = [3,9,20,null,null,15,7]
输出: true
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isBalanced = function(root) {
let res = true;
const dfs = (root) => {
if(!root) return 0;
let left = dfs(root.left);
let right = dfs(root.right);
if(Math.abs(left - right) > 1) res = false;
return Math.max(left, right) + 1;
}
dfs(root);
return res;
};
104. 二叉树的最大深度
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
const dfs = (root) => {
if(!root) return 0;
return Math.max(dfs(root.left), dfs(root.right))+1;
}
return dfs(root);
};
111. 二叉树的最小深度
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
输入: root = [3,9,20,null,null,15,7]
输出: 2
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
const dfs = (root) => {
if(!root) return 0;
if(!root.left) return dfs(root.right) + 1;
if(!root.right) return dfs(root.left) + 1;
return Math.min(dfs(root.left), dfs(root.right)) + 1;
}
return dfs(root);
};
563. 二叉树的坡度
一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。
整个树 的坡度就是其所有节点的坡度之和。
输入:root = [4,2,9,3,5,null,7]
输出:15
解释:
节点 3 的坡度:|0-0| = 0(没有子节点)
节点 5 的坡度:|0-0| = 0(没有子节点)
节点 7 的坡度:|0-0| = 0(没有子节点)
节点 2 的坡度:|3-5| = 2(左子树就是左子节点,所以和是 3 ;右子树就是右子节点,所以和是 5 )
节点 9 的坡度:|0-7| = 7(没有左子树,所以和是 0 ;右子树正好是右子节点,所以和是 7 )
节点 4 的坡度:|(3+5+2)-(9+7)| = |10-16| = 6(左子树值为 3、5 和 2 ,和是 10 ;右子树值为 9 和 7 ,和是 16 )
坡度总和:0 + 0 + 0 + 2 + 7 + 6 = 15
/**
* @param {TreeNode} root
* @return {number}
*/
var findTilt = function(root) {
let res = 0;
const dfs = (root) => {
if(!root) return 0;
let left = dfs(root.left);
let right = dfs(root.right);
res += Math.abs(left - right);
return left + right + root.val;
}
dfs(root);
return res;
};
98. 验证二叉搜索树
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
输入: root = [2,1,3]
输出: true
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function (root) {
const dfs = (root, min, max) => {
if(!root) return true;
if(root.val >= max || root.val <= min) return false;
return dfs(root.left, min, root.val) && dfs(root.right, root.val, max);
}
return dfs(root, -Infinity, Infinity);
};
112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。
叶子节点 是指没有子节点的节点。
输入: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出: true
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {boolean}
*/
var hasPathSum = function(root, targetSum) {
let res = false;
const dfs = (root, sum) => {
if(res || !root) return;
sum += root.val;
if(!root.left && !root.right) {
if(sum === targetSum) res = true;
return;
}
if(root.left) dfs(root.left, sum);
if(root.right) dfs(root.right, sum);
}
dfs(root, 0);
return res;
};
113. 路径总和 II
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {number[][]}
*/
var pathSum = function(root, targetSum) {
let res = [];
const dfs = (root, sum, path) => {
if(!root) {
return;
}
sum += root.val;
path.push(root.val);
if(!root.left && !root.right) {
if(sum === targetSum) res.push(path.slice());
}
if(root.left) dfs(root.left, sum, path);
if(root.right) dfs(root.right, sum, path);
path.pop();
}
dfs(root, 0, []);
return res;
};