题目描述

请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
刚开始的思路:由于题目中说如果与其镜像二叉树相同,那么就是对称的,那我就先建立该二叉树的镜像二叉树,然后比较这两颗二叉树是否一样。
建立镜像二叉树,需要先建立根结点,因为根结点肯定都是一致的,然后递归建立当前结点的左右孩子结点,在建立时将其左右孩子交换,
比较镜像二叉树与当前二叉树:刚开始主要是在递归结束条件处没有思路,应该是两个节点都为空返回true,有一个结点不为空就要返回false,如果两个节点都不为空,那么比较两者的值,如果不相等返回false,如果相等接着向下比较。
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot)
    {
        if(!pRoot) return true;
        TreeNode* mirrorRoot = new TreeNode(pRoot->val);
        mirrorTree(pRoot,mirrorRoot);
        bool flag=true;
        isSymmetrical2(pRoot,mirrorRoot,flag);
        return flag;
    }
    void mirrorTree(TreeNode* pRoot,TreeNode* mirrorRoot){
        if(pRoot){
            TreeNode* mirrorLeft = NULL;
            TreeNode* mirrorRight = NULL;
            if(pRoot->right){
                mirrorLeft = new TreeNode(pRoot->right->val);
            }
            if(pRoot->left){
                mirrorRight = new TreeNode(pRoot->left->val);
            }
            mirrorRoot->left = mirrorLeft;
            mirrorRoot->right = mirrorRight;
            mirrorTree(pRoot->left,mirrorRoot->right);
            mirrorTree(pRoot->right,mirrorRoot->left);
        }
    }
   void isSymmetrical2(TreeNode* pRoot,TreeNode* mirrorRoot,bool &flag){
       if(pRoot&&!mirrorRoot || !pRoot&&mirrorRoot)
            flag = false;
        if(flag&&pRoot&&mirrorRoot){
            if(pRoot->val!=mirrorRoot->val)
                flag = false;
            else
                flag = true;
        
            isSymmetrical2(pRoot->left,mirrorRoot->left,flag);
            isSymmetrical2(pRoot->right,mirrorRoot->right,flag);
        }
        
        
    }
};

 后来,我发现根本不需要建立镜像二叉树就可以得出结果,只需要return isSymmetrical(pRoot->left,mirrorRoot->right)&&isSymmetrical(pRoot->right,mirrorRoot->left)左子树节点和右子树节点进行比较,右子树节点和左子树节点进行比较,这样的话,减少了空间的使用但是增加了时间的消耗。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot)
    {
        if(!pRoot) return true;
        return isSymmetrical(pRoot->left,pRoot->right);
    }
   bool isSymmetrical(TreeNode* pRoot,TreeNode* mirrorRoot){
        if(!pRoot && mirrorRoot || pRoot&&!mirrorRoot)
            return false;
        if(!pRoot&&!mirrorRoot)
            return true;
        if(pRoot->val!=mirrorRoot->val)
            return false;
        return isSymmetrical(pRoot->left,mirrorRoot->right)&&isSymmetrical(pRoot->right,mirrorRoot->left);
    }
};

 

 

 接着,我又使用了java实现了它的非递归算法,我的思路是,层次遍历,一层一层遍历,将每一层的值放到队列和栈中,然后依次出队列,出栈(即判断是否是回文),但是这种情况只在满二叉树可用,需要在层次遍历的时候遇到空节点的时候,在栈和队列中弹入-1,即可实现该问题。

import java.util.Queue;
import java.util.LinkedList;
import java.util.Stack;
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot == null) return true;
        Queue<TreeNode> queueRoot = new LinkedList<>();
        Queue<Integer> queueOrder = new LinkedList<>();
        Stack<Integer> stackReverse = new Stack<>();
        TreeNode q;
        int qSize = 0;
        
        queueRoot.add(pRoot);
        while(!queueRoot.isEmpty()){
            qSize = queueRoot.size();
            //一层一层遍历
            for(int i=0;i<qSize;i++){
                q = queueRoot.poll();
                if(q == null){//如果是空,那么就将-1入栈入队列
                    queueOrder.add(-1);
                    stackReverse.push(-1);
                }else{
                    queueOrder.add(q.val);
                    stackReverse.push(q.val);
                    queueRoot.add(q.left);
                    queueRoot.add(q.right);
                }
            }
            //判断这层的数据是不是回文
            while(!queueOrder.isEmpty() && !stackReverse.empty()){
                if(queueOrder.peek() != stackReverse.peek())
                    return false;
                queueOrder.poll();
                stackReverse.pop();
            }
        }
        return true;
    }
}

 

 接着,我又在评论区看了其他大神的思路,得到了对于非递归遍历更加简便的方法,其实就是一个从左往右入队列遍历,一个从右往左入队列遍历,然后进行判断,判断的方法与递归的判断条件一致。

import java.util.Queue;
import java.util.LinkedList;
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot == null) return true;
        Queue<TreeNode> queueOrder = new LinkedList<>();
        Queue<TreeNode> queueReverse = new LinkedList<>();
      //这里改成了将左子树根节点和右子树根节点分别入队列,因为如果是对称的话,其左右子树应该是对称的

      queueOrder.add(pRoot.left);
      queueReverse.add(pRoot.right);

        TreeNode q1;
        TreeNode q2;
        while(!queueOrder.isEmpty() && !queueReverse.isEmpty()){
            q1 = queueOrder.poll();
            q2 = queueReverse.poll();
            if(q1 == null && q2 == null)
                continue;
            if(q1 == null || q2 == null)
                return false;
            if(q1.val != q2.val)
                return false;
            queueOrder.add(q1.left);
            queueOrder.add(q1.right);
            queueReverse.add(q2.right);
            queueReverse.add(q2.left);
        }
        return true;
    }
}

 

 

 

 

 

 

posted on 2020-08-11 20:35  曹婷婷  阅读(122)  评论(0编辑  收藏  举报