对称的二叉树|刷题打卡

88 阅读2分钟

掘金团队号上线,助你 Offer 临门! 点击 查看详情

一、题目描述

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

示例:

例如,二叉树 [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

输入:

root = [1,2,2,3,4,4,3]
root = [1,2,2,null,3,null,3]

输出:

true
false

限制

0 <= 节点个数 <= 1000

二、思路分析

我的思路

  • 考虑使用层次遍历然后计算这一层上所有节点是否对称就可以了
  • 我以为层次遍历的方式去判断会比递归好些,但其实不是这样。
    • 递归的思想也很简单,递归函数传入2个节点:一个最左边的,一个最右边的

最佳思路

  • 采用递归去做,
    • 先确认下递归的函数要干什么?
      • 函数的作用是判断传入的两个树是否镜像。
      • 输入:TreeNode left, TreeNode right
      • 输出:是:true,不是:false
    • 递归停止的条件是什么?
      • 左节点和右节点都为空 -> 到底部了都长得一样 ->true
      • 左节点为空的时候右节点不为空,或反之 -> 长得不一样-> false
      • 左右节点值不相等 -> 长得不一样 -> false
    • 从某层到下一层的关系是什么?
      • 要想两棵树镜像,那么一棵树左边的左边要和二棵树右边的右边镜像,一棵树左边的右边要和二棵树右边的左边镜像
      • 调用递归函数传入左左和右右
      • 调用递归函数传入左右和右左
      • 只有左左和右右镜像且左右和右左镜像的时候,我们才能说这两棵树是镜像的!

三、AC 代码

我的写法:

// 采用的层次遍历去做的,结果很复杂
public boolean isSymmetric(TreeNode root) {
    if (root == null) {
        return true;
    }
    List<TreeNode> levelNodes = new ArrayList<
    levelNodes.add(root.left);
    levelNodes.add(root.right);
    while (true) {
        int index = 0;
        // 比较一层是否相同
        while (true) {
            TreeNode pre = levelNodes.get(inde
            TreeNode last = levelNodes.get(lev
            if (pre != null && last != null) {
                if (pre.val != last.val) {
                    return false;
                }
            } else {
                if (pre != last) {
                    return false;
                }
            }
            index++;
            if (index > (levelNodes.size() / 2
                break;
            }
        }
        //添加下一层
        boolean allNull = true;
        List<TreeNode> newLevelNodes = new Arr
        for (TreeNode n : levelNodes) {
            if (n != null) {
                if (n.left != null || n.right 
                    allNull = false;
                }
                newLevelNodes.add(n.left);
                newLevelNodes.add(n.right);
            }
        }
        if (allNull) {
            return true;
        }
        levelNodes = newLevelNodes;
    }
}

最佳写法

public boolean isSymmetricBetter(TreeNode root) {
    return root == null || recur(root.left, root.right);
}
/**
 * 递归
 */
boolean recur(TreeNode L, TreeNode R) {
    if (L == null && R == null) {
        return true;
    }
    if (L == null || R == null || L.val != R.val) {
        return false;
    }
    // 左子树的左边和右子树的右边去比较, 左子树的右边,和右子树的左边进行比较 --- 这点清楚了很重要
    return recur(L.left, R.right) && recur(L.right, R.left);
}

四、总结

主要考的是递归的思路是否清晰!