题目描述
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
示例 1:
二叉树 [1,2,2,3,4,4,3] 是对称的。
    1
   / \
  2   2
 / \ / \
3  4 4  3
示例 2:
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
    1
   / \
  2   2
   \   \
   3    3
解题思路
方法一:递归分析
时间复杂度:$O(N)$
空间复杂度:$O(N)$
代码如下
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root==NULL)  return true;
        return isSymmetricHelper(root->left, root->right);
    }
    bool isSymmetricHelper(TreeNode *left, TreeNode *right){
        if(left==NULL && right==NULL)   return true;
        if( left==NULL || right==NULL || left->val!=right->val )  return false;
        return  isSymmetricHelper(left->right,right->left) && isSymmetricHelper(left->left, right->right);
    }
};
解法分析
每一次递归传进左子树指针和右子树指针。终止条件为下面几种情况:
- 左右子树都为空,返回$True$
 - 左右子树值不等或者只有一边为空,返回$False$
 - 返回递归函数,函数参数是左子树的左子树和右子树的右子树比较;与左子树的右子树和右子树的左子树比较。
 
方法二:辅助栈方法
时间复杂度:$O(N)$
空间复杂度:$O(N)$
代码如下
//摘自LeetCode中sdwwld大佬
public boolean isSymmetric(TreeNode root) {
    //队列
    Queue<TreeNode> queue = new LinkedList<>();
    if (root == null)
        return true;
    //左子节点和右子节点同时入队
    queue.add(root.left);
    queue.add(root.right);
    //如果队列不为空就继续循环
    while (!queue.isEmpty()) {
        //每两个出队
        TreeNode left = queue.poll(), right = queue.poll();
        //如果都为空继续循环
        if (left == null && right == null)
            continue;
        //如果一个为空一个不为空,说明不是对称的,直接返回false
        if (left == null ^ right == null)
            return false;
        //如果这两个值不相同,也不是对称的,直接返回false
        if (left.val != right.val)
            return false;
        //这里要记住入队的顺序,他会每两个两个的出队。
        //左子节点的左子节点和右子节点的右子节点同时
        //入队,因为他俩会同时比较。
        //左子节点的右子节点和右子节点的左子节点同时入队,
        //因为他俩会同时比较
        queue.add(left.left);
        queue.add(right.right);
        queue.add(left.right);
        queue.add(right.left);
    }
    return true;
}
解法分析
解法分析看上面代码注释