zoukankan      html  css  js  c++  java
  • 剑指offer(五十八):对称的二叉树

    题目描述

    请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
    刚开始的思路:由于题目中说如果与其镜像二叉树相同,那么就是对称的,那我就先建立该二叉树的镜像二叉树,然后比较这两颗二叉树是否一样。
    建立镜像二叉树,需要先建立根结点,因为根结点肯定都是一致的,然后递归建立当前结点的左右孩子结点,在建立时将其左右孩子交换,
    比较镜像二叉树与当前二叉树:刚开始主要是在递归结束条件处没有思路,应该是两个节点都为空返回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;
        }
    }

     

  • 相关阅读:
    【数据分析师 Level 1 】17.分类分析
    【数据分析师 Level 1 】16.回归分析
    【数据分析师 Level 1 】15.因子分析
    【数据分析师 Level 1 】14.主成分分析
    2020年年终总结
    【数据分析师 Level 1 】13.数据预处理方法
    【数据分析师 Level 1 】12.数据探索和可视化
    【数据分析师 Level 1 】11.市场调研
    一些关于angular的总结
    Git
  • 原文地址:https://www.cnblogs.com/ttzz/p/13473518.html
Copyright © 2011-2022 走看看