【算法】对称二叉树

69 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

题目

给你一个二叉树的根节点 root , 检查它是否轴对称。

解题思路

二叉树的镜像对称条件:

  1. 左节点 == 右节点。
  2. 每个节点上的左右子节点同样的和另外对称一个节点满足条件1
  3. 左边节点的左子节点和右边节点的右子节点比较;左边节点的右子节点和右边节点的左子节点比较。具体如下图所示

递归遍历法

采用递归法求解首先设置终止条件,然后做递归操作,最后输出结果。

  1. 终止条件满足以下几点:左右无节点表示遍历结束以及左右对称;左右节点值不相等;但以上条件都不满足也是终止。
  2. 左右节点不为空则判断左右节点是否相等;相等则继续判断这两个节点子节点情况。
    public boolean isSame(TreeNode left,TreeNode right){
        if((left == null && right == null)) return true; // 左右都为空也是对称的表现
         if((left != null && right != null)){ // 不为空是
             if(left.val != right.val) return false; // 判断值是否相同
             // 相同就继续遍历下一个节点
             return isSame(left.left,right.right) && isSame(left.right,right.left);
         }
         return false; // 其他情况都是不对称情况
    } 
    public boolean isSymmetric(TreeNode root) {
        TreeNode left = root.left;
        TreeNode right = root.right;
        return isSame(left,right);
    }

迭代解法

迭代解法可实现解法虽然解法看起来比较复杂但有必要学习一下其解题思路。迭代解法主要是运用队列先进先出能力,将根节点放入到队列中去,在通过循环不断取左右节点做比较判断是否对称。

  1. 双根节点放入队列以获取左右节点,同时判断细节条件(节点是否为空等
  2. 分别将左右节点(a、b)的左节点 (a)右节点(b)以及左节点 (b)右节点(a)放入队列(下次循环时用于比较
  3. 循环队列直到队列空位为止表明树是对称的。
public boolean isSymmetric(TreeNode root) {
        return check(root, root);
    }

    public boolean check(TreeNode u, TreeNode v) {
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(u);
        q.offer(v);
        while (!q.isEmpty()) {
            u = q.poll();
            v = q.poll();
            if (u == null && v == null) {
                continue;
            }
            if ((u == null || v == null) || (u.val != v.val)) {
                return false;
            }
        	// 解题思路中提到的判断逻辑
            q.offer(u.left);
            q.offer(v.right);

            q.offer(u.right);
            q.offer(v.left);
        }
        return true;
    }

参考