携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
成熟不过是善于隐藏,沧桑不过是无泪有伤...
题目描述
原题链接:101-对称二叉树
给你一个二叉树的根节点
root, 检查它是否轴对称。
- 测试用例一
输入: root = [1,2,2,3,4,4,3]
输出: true
- 测试用例二
输入: root = [1,2,2,null,3,null,3]
输出: false
提示:
- 树中节点数目在范围
[1, 1000]内 -100 <= Node.val <= 100
思路
- 前端常见的树包括:DOM、树、级联选择、树形控件……。
JavaScript中没有树,但是可以通过Object和Array构建树,力扣里面的树每个节点只有两个下游节点
//建树
class TreeNode {
val: number
left: TreeNode | null
right: TreeNode | null
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
}
- 判断二叉树是否对称,只需要比较子树的对称位置是否相同,也就是说,左子树的左侧对应右子树的右侧,左子树右侧对应右子树左侧
- 迭代法就是用队列,将判断互为镜像的节点添加到队列中,然后做比较是否相等
- 递归法是把两个树的左子树和右子树作为递归函数的入参,再判断树1的左子树和树2的右子树是否镜像,树1的右子树和树2的左子树是否镜像,当且仅当判断都成立并且根节点也相同,那么就是对称的
Code
/** 递归版 */
const isSymmetric1 = (root: TreeNode | null): boolean => root? dfs(root.left, root.right): true
//递归函数
const dfs = (l, r) => {
if (!l && !r) {
return true; //左右都为空=>对称
}
if (!l || !r) {
return false; //左右只有一个为空不对称
}
if (l.val !== r.val) {
return false; //两个镜像节点val不同不对称
}
return dfs(l.left, r.right) && dfs(l.right, r.left);
};
/** 迭代版 */
const isSymmetric2 = (root: TreeNode | null): boolean => {
if (!root) return true;
const queue = [root.left, root.right]; // 将左、右子树头结点入队
while (queue.length) {
const u = queue.shift(); // 将左子树头结点出队
const v = queue.shift(); // 将右子树头结点出队
if (!u && !v) continue;
if (!u || !v || u.val !== v.val) return false; // 左右只有一个为空,或者都不为空但数值不相同,不对称
queue.push(u.left, v.right); //左树左节点和右树右节点入队
queue.push(v.left, u.right); //右树左节点和左树右节点入队
}
return true;
};
复杂度分析
- 时间复杂度:递归和迭代都是
O(n)每个节点遍历一次 - 空间复杂度:递归和迭代都是
O(n)
相关题目推荐
这两道题目基本和本题是一样的,只要稍加修改就可以AC。
- 100.相同的树
- 572.另一个树的子树