LeetCode题解-101-Symmetric Tree

原题


链接:https://leetcode.com/problems/symmetric-tree/


解法概览

本题共有3种解法,解法1为别人的解答,解法2为参考别人思路后改造:https://discuss.leetcode.com/topic/5941/recursive-and-non-recursive-solutions-in-java

解法1:递归法

解法2:迭代法,基于BFS

解法4:迭代法,基于DFS


解法1

解法分析

递归法。

最小的分析单元为1+2+4个节点,对于一个节点来说,如果2个子节点不对称或者4个孙节点不对称,那么该树就不对称;如果对称,需要进一步判断其他的节点,判断顺序为自顶向上。


代码

public class Solution101_recursive {
    public boolean isSymmetric(TreeNode root) {
        return root == null || isSymmetricHelper(root.left, root.right);
    }

    private boolean isSymmetricHelper(TreeNode left, TreeNode right) {
        if (left == null || right == null)
            return left == right;
        if (left.val != right.val)
            return false;
        return isSymmetricHelper(left.left, right.right) && isSymmetricHelper(left.right, right.left);
    }
}

解法2

解法分析

迭代法,基于BFS。使用了队列,具体思路与图解类似于LeetCode题解-104-Maximum Depth of Binary Tree,但是不同的是每层节点中是外侧的节点先进队列。

代码

public class Solution101_BFS_iterator {
    public boolean isSymmetric(TreeNode root) {
        if (root == null)
            return true;

        TreeNode leftNode, rightNode;
        Deque<TreeNode> deque = new LinkedList<TreeNode>();
        if (root.left != null){
            if (root.right == null)
                return false;
            deque.push(root.left);
            deque.push(root.right);
        }
        else if (root.right != null)
            return false;

        while (!deque.isEmpty()){
            if (deque.size() % 2 != 0)
                return false;
            rightNode = deque.pop();
            leftNode = deque.pop();
            if (rightNode.val != leftNode.val)
                return false;

            if (leftNode.left != null){
                if (rightNode.right == null)
                    return false;
                deque.addLast(leftNode.left);
                deque.addLast(rightNode.right);
            }
            else if (rightNode.right != null)
                return false;

            if (leftNode.right != null){
                if (rightNode.left == null)
                    return false;
                deque.addLast(leftNode.right);
                deque.addLast(rightNode.left);
            }
            else if (rightNode.left != null)
                return false;
        }
        return true;
    }
}

解法3

解法分析

同时进行2个后序遍历。

一个迭代器进行标准的后序遍历:1)后序遍历左子树,2)后序遍历右子树,3)访问根节点;

一个迭代器进行镜像的后序遍历:1)后序遍历右子树,2)后序遍历左子树,3)访问根节点;

如果两个迭代器在每次遍历时取出的节点的值都相同,那么这棵树就是对称的。

后序遍历的解题思路与图解请见:LeetCode题解-145-Binary Tree Postorder Traversal


代码

public class Solution101_DFS_iterator {
    public boolean isSymmetric(TreeNode root) {
        TreeNode leftIterator = root, rightIterator = root;
        TreeNode leftLastVisit = null, rightLastVisit = null;
        Deque<TreeNode> leftStack = new LinkedList<TreeNode>(), rightStack = new LinkedList<TreeNode>();
        int leftDepth= 0, rightDepth = 0;
        if (leftIterator != null)
            leftStack.push(leftIterator);
        if (rightIterator != null)
            rightStack.push(rightIterator);

        while (!leftStack.isEmpty() && !rightStack.isEmpty()){
            while (leftStack.peek() != null){
                TreeNode currentNode = leftStack.peek();
                leftStack.push(currentNode.left);
                leftDepth++;
            }
            leftStack.pop();
            while (rightStack.peek() != null){
                TreeNode currentNode  = rightStack.peek();
                rightStack.push(currentNode.right);
                rightDepth++;
            }
            rightStack.pop();

            if (!leftStack.isEmpty()){
                TreeNode leftStackCurrentNode = leftStack.peek();
                if (leftStackCurrentNode.right == null || leftStackCurrentNode.right == leftLastVisit){
                    leftLastVisit = leftStack.pop();
                    leftStack.push(null);
                    leftDepth--;
                }
                else{
                    leftStack.push(leftStackCurrentNode.right);
                }
            }

            if (!rightStack.isEmpty()){
                TreeNode rightStackCurrentNode = rightStack.peek();
                if (rightStackCurrentNode.left == null || rightStackCurrentNode.left == rightLastVisit){
                    rightLastVisit = rightStack.pop();
                    rightStack.push(null);
                    rightDepth--;
                }
                else{
                    rightStack.push(rightStackCurrentNode.left);
                }
            }

            if (leftDepth != rightDepth)
                return false;

            if (leftLastVisit == null && rightLastVisit == null)
                continue;
            else if (leftLastVisit == null && rightLastVisit != null)
                return false;
            else if (leftLastVisit != null && rightLastVisit == null)
                return false;
            else if (leftLastVisit.val != rightLastVisit.val)
                return false;
        }
        return true;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值