101. 对称二叉树 Java解法

101. 对称二叉树

https://leetcode-cn.com/problems/symmetric-tree/
在这里插入图片描述

递归法:

其实这题的解法已经是很成熟的了,大概就是你需要比较当前根节点的两个叶子节点是否相等,然后再把相对应的节点一一继续比较,这就是判断二叉树是否对称的惯用解法。其实这个题目官方的解答不可谓不好,我们可以直接来看代码。

class Solution {
    public boolean isSymmetric(TreeNode root) {
       return isMirror(root, root);
    }

    public boolean isMirror(TreeNode leftNode, TreeNode rightNode) {
        if (leftNode == null && rightNode == null) {
            return true;
        } else if (leftNode == null || rightNode == null) {
            return false;
        } else if (leftNode.val != rightNode.val) {
            return false;
        }
        boolean node1 = isMirror(leftNode.left, rightNode.right);
        boolean node2 = isMirror(leftNode.right, rightNode.left);
        return node1 && node2;
    }
}

但是有一点就是,这种思路可能不会第一时间想到,那么我在这里提供另一种解答方法,虽然都是递归,但是我相信,这种思路应该会更加好理解的。
首先我们先明白『先序遍历』的顺序是:根 -> 左 -> 右
那么我们能否来一个『反先序遍历』呢?顺序就是:根 -> 右 -> 左
看到这里,你大概就能猜到了,接下来我们只要保证两个两个遍历的所经过的节点的值都是相同的,那么就是对称二叉树了。那么有着这种思路,我们来看一下代码:

class Solution {
    
    List<TreeNode>  proList = new LinkedList<>();
    List<TreeNode> unProList = new LinkedList<>();
    public boolean isSymmetric(TreeNode root) {
        proTraversing(root);
        unProTraversing(root);
        int len = proList.size();
        int unLen = unProList.size();
        if (len != unLen) {
            return false;
        } else {
            for (int i = 0; i < len; ++i) {
                if (proList.get(i) == null && unProList.get(i) == null) {
                    continue;
                } else if (proList.get(i) == null || unProList.get(i) == null) {
                    return false;
                } else if (proList.get(i).val != unProList.get(i).val) {
                    return false;
                }
            }
        }
        return true;
    }

    private void proTraversing(TreeNode node) {
        if (node == null) {
            proList.add(node);
            return;
        }
        proList.add(node);
        proTraversing(node.left);
        proTraversing(node.right);
    }


    private void unProTraversing(TreeNode node) {
        if (node == null) {
            unProList.add(node);
            return;
        }
        unProList.add(node);
        unProTraversing(node.right);
        unProTraversing(node.left);
    }
}

以上就是这个思路,其实速度不快,就是好理解。

迭代法:

其实这题,我只想到用递归,但是其实按理来说,如果你精通二叉树的层遍历,那么迭代法会更加简单,下面我直接引用官方的解答:

除了递归的方法外,我们也可以利用队列进行迭代。队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像。最初,队列中包含的是 root 以及 root。该算法的工作原理类似于 BFS,但存在一些关键差异。每次提取两个结点并比较它们的值。然后,将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

其实我觉得这解答写的,额。不咋好,有空我会根据我的思路重新做一做,我们先来看看官方的解答的代码:

public boolean isSymmetric(TreeNode root) {
    Queue<TreeNode> q = new LinkedList<>();
    q.add(root);
    q.add(root);
    while (!q.isEmpty()) {
        TreeNode t1 = q.poll();
        TreeNode t2 = q.poll();
        if (t1 == null && t2 == null) continue;
        if (t1 == null || t2 == null) return false;
        if (t1.val != t2.val) return false;
        q.add(t1.left);
        q.add(t2.right);
        q.add(t1.right);
        q.add(t2.left);
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值