102 lines
3.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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}
*/
// const isSymmetric = function (root) {
// return f1(root.left, root.right);
// };
/*
递归1.基础条件:如果两个树的根节点为空,则它们对称;如果一个为空而另一个不为空,则不对称;如果两个节点的值不相等,则不对称。
2.递归检查左右子树的对称性:左子树的左子树与右子树的右子树对称,左子树的右子树与右子树的左子树对称。
*/
function f1(left, right) {
// 如果左右两颗树的根节点都为空,则对称
if (!left && !right) return true;
// 上面判断排除了都为空的情况,所以至少有一颗树不为空,如果有的话,表明不对称
if (!left || !right) return false;
// 如果两个节点不为空两个节点的值不相等返回false
if (left.val !== right.val) return false;
// 递归的对称检查left.left和right.right, left.right和righ.left
return f1(left.left, right.right) && f1(left.right, right.left);
}
/*
使用bfs,使用两个队列left和right分别表示镜像每一层的左右节点然后检查left从左到右存节点
right从右到左存节点然后一一比较如果都相当则表明这一层是对称的继续检查下一层如果每一层
都是对称的就表明整颗树都是对称的
*/
function f2(root) {
const queueL = [root.left]; // 遍历镜像左边的节点
const queueR = [root.right]; // 遍历镜像右边的节点
// 每一层的节点个数
let leaveSize = 1;
while (queueL.length > 0) {
console.log('lq: ', queueL);
console.log('rq: ', queueR);
// 判断左右节点
for (let i = 0; i < leaveSize; i++) {
// 取出对应节点比较
const leftSideNode = queueL.shift();
const rightSideNode = queueR.shift();
// 如果两个节点都为空,直接跳过本次循环,根本就没有子节点,无需做后面的操作
if (!leftSideNode && !rightSideNode) continue;
// 如果两个节点一个为空直接返回false
if (!leftSideNode || !rightSideNode) return false;
// 左右两个节点值不相等
if (leftSideNode.val !== rightSideNode.val) return false;
// 将左侧和右侧的节点按照顺序压入栈中
queueL.push(leftSideNode.left);
queueL.push(leftSideNode.right);
queueR.push(rightSideNode.right);
queueR.push(rightSideNode.left);
}
leaveSize = queueL.length;
}
return true;
}
/*
dfs,只需一个循环依此检查即可,
*/
function f3(root) {
const stackL = [root.left]; // 遍历镜像左边的节点
const stackR = [root.right]; // 遍历镜像右边的节点
while (stackL.length > 0) {
// 拿出镜像左右两边的节点比较
const leftSideNode = stackL.pop();
const rightSideNode = stackR.pop();
// 如果两个值都为空就跳过
if (!leftSideNode && !rightSideNode) continue;
// 如果两个节点中有一个为null就返回false
if (!leftSideNode || !rightSideNode) return false;
// 如果两个节点都存在但是值不相等返回false
if (leftSideNode.val !== rightSideNode.val) return false;
// 将左右节点压入栈中leftSideNode.right->leftSideNode.left, rightSideNode.left->rightSideNode.right
stackL.push(leftSideNode.right);
stackL.push(leftSideNode.left);
stackR.push(rightSideNode.left);
stackR.push(rightSideNode.right);
}
return true;
}