BM23 二叉树的前序遍历(根-左-右)
方法一: 递归
function preorderTraversal( root ) {
const res = [];
if (!root) return res;
res.push(root.val);
root.left && res.push(...preorderTraversal(root.left));
root.right && res.push(...preorderTraversal(root.right));
return res;
}
var preorderTraversal = function(root) {
const result = [];
function fn(root) {
if(!root) return;
result.push(root.val);
fn(root.left);
fn(root.right);
}
fn(root);
return result;
};
方法二:非递归(栈)
function preorderTraversal( root ) {
const stack = [], res = [];
if (!root) return res;
stack.push(root)
while(stack.length) {
let node = stack.pop();
res.push(node.val);
node.right && stack.push(node.right);
node.left && stack.push(node.left);
}
return res;
}
BM24 二叉树的中序遍历(左-根-右)
方法一:递归
function inorderTraversal(root) {
const res = [];
if (!root) return res;
root.left && res.push(...inorderTraversal(root.left));
res.push(root.val);
root.right && res.push(...inorderTraversal(root.right));
return res;
}
方法二: 非递归(栈 )
function inorderTraversal(root) {
if (!root) return [];
const res = [], stack = [];
// 当树节点不为空或栈中有节点时
while(root || stack.length) {
// 每次找到最左节点
while(root) {
stack.push(root);
root = root.left;
}
// 访问节点
let node = stack.pop();
res.push(node.val);
// 进入右节点
root = node.right;
}
return res;
}
时间复杂度:O(n),其中n为二叉树的节点数,遍历二叉树所有节点
空间复杂度:O(n),辅助栈空间最大为链表所有节点数
BM25 二叉树的后序遍历(左-右-根)
方法一: 递归
function postorderTraversal( root ) {
const res = [];
let fn = function (root) {
if (!root) return;
root.left && fn(root.left);
root.right && fn(root.right);
res.push(root.val);
}
fn(root);
return res;
}
方法二: 非递归(栈)
function postorderTraversal( root ) {
const res = [], stack = [];
let pre;
while(root || stack.length) {
// 每次先找到最左边的节点
while(root) {
stack.push(root);
root = root.left;
}
let node = stack.pop();
// 如果该元素的右边没有或是已经访问过
if (!node.right || node.right === pre) {
// 访问中间的节点
res.push(node.val);
// 访问标记
pre = node;
} else {
// 当前节点入栈
stack.push(node);
// 访问右节点
root = node.right;
}
}
return res;
}
107. 二叉树的层序遍历
var levelOrderBottom = function(root) {
if (!root) return [];
const queue = [root], res = [];
while (queue.length) {
// 记录当前层的节点个数
let len = queue.length;
let arr = [];
for(let i = 0; i < len; i++) {
let node = queue.shift();
arr.push(node.val);
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.push(arr);
}
return res;
};
BM28 二叉树的最大深度
方法一: 层序遍历(记录层数)
方法二: 递归
function maxDepth( root ) {
if (!root) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
235. 二叉搜索树的最近公共祖先
题目:
思路: 利用二叉搜索树的特点,如果p、q的值都小于root,说明p q 肯定在root的左子树中;如果p q都大于root,说明肯定在root的右子树中,如果一个在左一个在右 则说明此时的root记为对应的最近公共祖先
var lowestCommonAncestor = function(root, p, q) {
if (p.val === root.val) return p;
if (q.val === root.val) return q;
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestor (root.left, p, q);
}
if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestor (root.right, p, q);
}
return root;
};
236. 二叉树的最近公共祖先
var lowestCommonAncestor = function(root, p, q) {
if (!root || p === root || q === root) return root;
let left = lowestCommonAncestor(root.left, p, q);
let right = lowestCommonAncestor(root.right, p, q);
if (!left && !right) return null;
else if (left && right) return root;
return left ? left : right;
};
222. 完全二叉树的节点个数
题目:
var countNodes = function(root) {
if (root === null) return 0;
let leftHigh = 0, rightHigh = 0;
let temp = root.left;
let result = 1;
while(temp) {
leftHigh++;
temp = temp.left;
}
temp = root.right;
while(temp) {
rightHigh++;
temp = temp.left;
}
let countChild = function(node) {
if (node === null) return 0;
return countChild(node.left) + countChild(node.right) + 1;
}
if (leftHigh === rightHigh) {
result += leftHigh ? Math.pow(2, leftHigh) - 1 : 0;
result += countChild(root.right);
} else {
result += rightHigh ? Math.pow(2, rightHigh) - 1 : 0;
result += countChild(root.left);
}
return result;
};
1123. 最深叶节点的最近公共祖先
题目:给你一个有根节点 root 的二叉树,返回它 最深的叶节点的最近公共祖先 。
// 计算深度
var deep = function (root) {
if (!root) return 0;
let l = deep(root.left);
let r = deep(root.right);
return 1 + Math.max(l, r);
}
var lcaDeepestLeaves = function(root) {
if (!root) return root;
let l = deep(root.left);
let r = deep(root.right);
if (l === r) return root;
if (l > r) {
return lcaDeepestLeaves(root.left);
} else {
return lcaDeepestLeaves(root.right);
}
};