【二叉树】对称二叉树(3种方法:递归、迭代、BFS)

题目描述

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

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

思路

判断二叉树是否对称,下边两种方法都可以判断:

法1:

假设从根节点(root)开始判断的话,假设他的左右两个孩子为n1和n2,也就是要判断两棵以节点n1、n2为根的子树是否对称。当然,如果n1和n2都为NULL的话,肯定是对称了。如果二者中只有一个为NULL,那一定不是对称的,除开这两种情况,第三种情况就是要判断n1的left和n2的right,n1的right和n2的left,这两个条件是否都成立,如果都成立则对称,否则不对称。
法1的思路其实就是递归的一个逻辑,每个给递归函数传入两个节点,判断这两个节点的对称情况即可。
递归也可转化为迭代,迭代的话就需要用队列来做辅助,递归函数中每次传入两个节点,那么在迭代中怎么做呢?用两个队列就好了q1和q2。当然,在往这两个队列里push节点的时候,要同时push处于对称位置的两个节点,然后取出的时候正好也是取出对称位置的两个节点,才可以判断下边的子树是否对称。

法2:

使用二叉树的层序遍历,如果一个二叉树是对称的,那么它的每一层一定也是对称的,使用BFS算法逐层判断,某一层不对称了,那整棵树就不是对称的。

使用vector按顺序存储一层中所有节点的val,如果该某个位置没有节点(为NULL),就用一个特殊的标记占位(必须占位,自己想想),都加入以后,将vector逆序一下,判断逆序前后是否相等,如果相等,则这一层就是对称的。

BFS中如何判断哪些节点在同一层呢?
比如从root出发,将root节点push到队列以后,队列的size为1,处理完size(1)个节点(处理完就弹pop掉了size个节点),也就证明这一层处理完了,再加入root的两个子节点,此时队列的size为2,处理完size(2)个节点,也就把第二层处理完了。通过size变量就可以知道哪些节点在同一层了。
下面上代码

代码(递归、迭代、BFS)

递归

class Solution {
    
    
public:
    
    bool judge(TreeNode* left, TreeNode* right){
    
    
        
        if(left == NULL and right == NULL){
    
    
            return true;
        }
        // 只有一个为空
        if(left == NULL or right == NULL){
    
    
            return false;
        }
        
        // 都不为空  
        return judge(left -> left, right -> right) and judge(left -> right, right -> left) and left -> val == right -> val;
        
        
        
    }
    
    
    bool isSymmetric(TreeNode* root) {
    
    
        if(root == NULL){
    
    
            return true;
        }

        // 递归法
        
         return judge(root -> left, root -> right);
 
    }
};

迭代

class Solution {
    
    
public:
    bool isSymmetric(TreeNode* root) {
    
    
        if(root == NULL){
    
    
            return true;
        }

        // 迭代法  递归 改迭代的话 需要用的队列来辅助
        queue<TreeNode*> q1, q2;
        q1.push(root -> left);
        q2.push(root -> right);
        
        while(!q1.empty() and !q2.empty()){
    
    
            
            TreeNode* node1 = q1.front();
            TreeNode* node2 = q2.front();
            
            q1.pop();
            q2.pop();
            
            // 都空 没事; 都不空 往下判断,  只有一个是NULL就返回false
            
            if( (node1 == NULL and node2 != NULL) or (node1 != NULL and node2 == NULL ) ){
    
    
                // 只有一个是NULL
                return false;
                
            }
            
            if(node1 != NULL and node2 != NULL){
    
    
                
                if(node1 -> val != node2 -> val){
    
    
                    return false;
                }else{
    
    
                    // val相同 往下判断  注意  q1 q2成对push,
                    q1.push(node1 -> left);
                    q2.push(node2 -> right);
                    
                    q1.push(node1 -> right);
                    q2.push(node2 -> left);
                    
                }
                
            }
            
                
            
        }
        
        
        
        return true;
        
        
        
    }
};

BFS

class Solution {
    
    
public:
    bool isSymmetric(TreeNode* root) {
    
    
        if(root == NULL){
    
    
            return true;
        }
        // 每一层都应该是对称的,用bfs取出每一层,每一层判断一下。
        
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
    
    
            
            int size = q.size();
            // size用来记录一层的节点数,处理了size个就是处理好了一层的
            vector<char> v;    // 因为这棵树中,有的只有左节点或者右节点,缺失的节点位置就需要用一个东西来填充上,如果用数字的话,就可能和node中的val相同了,所以用char中的*来占位,vector只好定义为char型
            for(int i = 0; i < size; i++){
    
    
                
                TreeNode* node = q.front();
                q.pop();
                if(node == NULL){
    
    
                    v.push_back('*');
                    continue;
                }
                
                v.push_back(char('0' + node -> val));
                // 把子节点加进去 等待处理
                q.push(node -> left);
                q.push(node -> right);
                   
            }
            // 一层处理完了,判断是否对称。
            vector<char> v2 = v;
            reverse(v2.begin(), v2.end());
            if(v != v2){
    
    
                return false;
            }
            

        }
        
        return true;

    }
};

猜你喜欢

转载自blog.csdn.net/u014117943/article/details/106262861
今日推荐