不一定是最优解 但都是些比较好理解的解法!!
二叉树先序遍历
var preorderTraversal = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
res.push(root.val) // 访问根节点的值
traversal(root.left) // 递归遍历左子树
traversal(root.right) // 递归遍历右子树
}
}
traversal(root)
return res
}
二叉树中序遍历
var inorderTraversal = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
traversal(root.left) // 递归遍历左子树
res.push(root.val) // 访问根节点的值
traversal(root.right) // 递归遍历右子树
}
}
traversal(root)
return res
}
二叉树后序遍历
var postorderTraversal = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
traversal(root.left) // 递归遍历左子树
traversal(root.right) // 递归遍历右子树
res.push(root.val) // 访问根节点的值
}
}
traversal(root)
return res
}
var isSameTree = function(p, q) {
function traversal (root1, root2) {
if (root1 === null && root2 !== null) {
return false
} else if (root1 !== null && root2 === null) {
return false
} else if (root1 === null && root2 === null) {
return true
} else {
return root1.val === root2.val && traversal(root1.left, root2.left) && traversal(root1.right, root2.right)
}
}
return traversal(p, q)
}
const invertTree = (root) => {
if (root == null) { // 遍历到null节点时,不用翻转,直接返回它本身
return root;
}
invertTree(root.left);
invertTree(root.right);
const temp = root.left;
root.left = root.right;
root.right = temp;
return root;
};
var postorder = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
root.children.forEach(child => {
traversal(child)
})
res.push(root.val)
}
}
traversal(root)
return res
}
var preorder = function(root) {
const res = []
let traversal = function (root) {
if (root === null) {
return
}
res.push(root.val)
root.children.forEach(function (child) {
traversal(child)
})
return
}
traversal(root)
return res
}
二叉树的层序遍历
var levelOrder = function(root) {
if (!root) return [];
const queue = [root];
const res = []; // 存放遍历结果
let level = 0; // 代表当前层数
while (queue.length) {
res[level] = []; // 第level层的遍历结果
let levelNum = queue.length; // 第level层的节点数量
while (levelNum--) {
const front = queue.shift();
res[level].push(front.val);
if (front.left) queue.push(front.left);
if (front.right) queue.push(front.right);
}
level++;
}
return res;
}
二叉树的最大深度
var maxDepth = function(root) {
if(!root) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
};
// 解法1
var isBalanced = function(root) {
// 遍历到底还没有发现高度差超过 1 的左右子树,那么这个子树肯定符合平衡二叉树的规范
if (!root) {
return true
}
// 判断左右子树的高度差,如果超过 1 那么立即返回 false
if (Math.abs(getHeight(root.left) - getHeight(root.right)) > 1) {
return false
}
// 分别递归左右子树
return isBalanced(root.left) && isBalanced(root.right)
// 获取某个子树的高度
function getHeight (root) {
if (!root) {
return 0
}
return Math.max(getHeight(root.left), getHeight(root.right)) + 1
}
};
// 解法2 优质解法
var isBalanced = function (root) {
return balanced(root) !== -1
};
var balanced = function (node) {
if (!node) return 0
const left = balanced(node.left)
const right = balanced(node.right)
if (left === -1 || right === -1 || Math.abs(left - right) > 1) {
return -1
}
return Math.max(left, right) + 1
}
const lowestCommonAncestor = (root, p, q) => {
if (root == null) { // 遇到null,返回null 没有LCA
return null;
}
if (root == q || root == p) { // 遇到p或q,直接返回当前节点
return root;
}
// 非null 非q 非p,则递归左右子树
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
// 根据递归的结果,决定谁是LCA
if (left && right) {
return root;
}
if (left == null) {
return right;
}
return left;
};
const isSymmetric = (root) => {
const check = (left, right) => {
if (left == null && right == null) { // 两个子树都为null,是对称的
return true;
}
if (left && right) { // 两个子树都存在,则需要:root值相同,且他们的子树也满足镜像
return left.val == right.val && check(left.left, right.right) && check(left.right, right.left);
}
return false; // 一个子树存在一个不存在,肯定不对称
};
if (root == null) { // 如果传入的root就是null,对称
return true;
}
return check(root.left, root.right); // 否则,判断它的左右子树是否满足对称
};