LeetCode刷题: 【101】对称二叉树

1. 题目

给定一个二叉树,检查它是否是镜像对称的。

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

说明:

如果你可以运用递归和迭代两种方法解决这个问题,会很加分。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 思路

如果一个二叉树对称,那么他的根节点的左子树(L)和右子树( R)一定是镜像关系,即:

1. L树的根等于R树的根
2. L树的左子树和R树的右子树呈镜像关系
3. L树的右子树和R树的左子树呈镜像关系

基准条件: 镜像节点不等返回false,镜像节点都等于null返回true
递归条件: 镜像节点相等

迭代思路:以镜像顺序分别遍历左右子树,若某个镜像节点值不等则返回false,若遍历完成则返回true

3. 递归实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return isMirror(root.left, root.right);
    }
    
    public boolean isMirror(TreeNode left, TreeNode right) {

        if(left == null){
            if(right == null) return true;
            else return false;
        }else {
            return right != null 
            && left.val == right.val 
            && isMirror(left.left, right.right) 
            && isMirror(left.right, right.left);
        }
        
    }
}

4. 迭代实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        
        if(root == null) return true;
        
        // 手动进行栈管理
        LinkedList<TreeNode> l = new LinkedList<TreeNode>();
        LinkedList<TreeNode> r = new LinkedList<TreeNode>();
        
        // 将左右子树压栈
        l.push(root.left);
        r.push(root.right);
       
       	// 在循环中从镜像顺序遍历左右子树,值相同则继续,否则返回false,遍历完成返回true 
        while(true){
        	// 空树 弹栈
            if(l.peek() == null){
                if(r.peek() == null) {
                    TreeNode cl,cr;
                    do{// 若当前分别处于后序节点,则多次弹栈
                        cl = l.pop();
                        cr = r.pop();
                        if(l.isEmpty() && r.isEmpty()) return true;// 遍历完成
                    } while(l.peek().right == cl && r.peek().left == cr);
                    l.push(l.peek().right);// 分别将后序节点压栈
                    r.push(r.peek().left);
                }
                else return false;// 镜像节点不相等
            }else{
                if(r.peek() != null && r.peek().val == l.peek().val) {
                    l.push(l.peek().left);// 分别将先序节点压栈
                    r.push(r.peek().right);
                }
                else return false;// 镜像节点不相等
            }
        }
        
        
    }
    
}

你可能感兴趣的:(文章,算法,LeetCode)