zoukankan      html  css  js  c++  java
  • leetcode--101. 对称二叉树--深度遍历优先

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

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

    解析: 首先注意一点,我是在按分类来找题目做的,这个简单题给了我个教训,不是分类就一定要用分类上的办法。
    我先写的迭代方法,因为一般来说,迭代比递归难点,我想法就是对每一层进行回文判断,但是忽略了题意,树不是每一层都是满的,不能单纯的直接使用pow(2,levelSize)来计算结果 注意变通。

    不要为了去用而去用 目的是提高自己的思维能力

    我写的迭代版本

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        queue<TreeNode*> Queue; //bfs需要的队列
        vector<TreeNode*> Array;    //存放当前层的节点
        bool isSymmetric(TreeNode* root) {
            if (root == NULL)
                return true;
            int level = 0;  //当前层数
            int levelSize = 1;  //当前层数应该比较的数目
            int nextSize = 0; //下层应该比较的数目
            Queue.push(root);  //开始条件
            TreeNode* temp;
            while(!Queue.empty()) {
                temp = Queue.front();
                Queue.pop();
                Array.push_back(temp);
    
                if(temp!=NULL){
                    Queue.push(temp->left);
                    Queue.push(temp->right);
                    nextSize += 2;
                }
    
                if(--levelSize == 0){    //当前层全部读出 进行判断
                    if(!checkThisLevel())  //存在冲突 不是镜像对称
                        return false;
                    else {
                        Array.clear();
                        level++;
                        levelSize = nextSize; //树的每层个数是2的n次
                        nextSize = 0;
                    }
                }
            }
            return true;
        }
        
        bool checkThisLevel() {
            int size = Array.size();
            for(int i = 0;i<(size+1)/2;i++){
                if(Array[i]==NULL && Array[size-1-i]== NULL)
                    continue;
                else if (Array[i] == NULL || Array[size-1-i] == NULL)
                    return false;
                else if(Array[i]->val != Array[size-1-i]->val)
                    return false;
            }
            return true;
        }
    };
    

    递归版本

    class Solution {
    public:
        bool isSymmetric(TreeNode* root) {
            return check(root->left,root->right);
        }
    
        bool check(TreeNode* left,TreeNode* right) {
            if(left==NULL && right==NULL)
                return true;
            if(left!=NULL && right!=NULL && left->val == right->val)
                return check(left->left,right->right) && check(left->right,right->left);
            else
                return false;
        }
    };
    

    比较好的迭代版本 其实就是递归想法的转化 我们每次比较的是一层中从左端开始序列 和 从右端开始序列

    这样我们每次存放队列时,可以不是按每层从左到右的顺序存放,因为每层数量是不固定的(这就是另一种做法 知道每层的数目) 我们可以存一个最左端的(未存放中最左的) 再存一个最右端的(未存放中最右的)

    这样每次弹出俩个来就是我们应该比较的对象了

    注意的点:

    1. 层序遍历的变种 按层来遍历 但并不一定要按照从左到右的方式来进行遍历
    2. 指针的声明 Treenode * node1,node2 是错误的方法
      Treenode *node1, *node2 才是正确的
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        bool isSymmetric(TreeNode* root) {
            queue<TreeNode*> Queue;
            if(root == NULL)
                return true;
            else {
                Queue.push(root->left);
                Queue.push(root->right);
            }
            TreeNode *node1,*node2;
            while(!Queue.empty()) {
                node1 = Queue.front();
                Queue.pop();
                node2 = Queue.front();
                Queue.pop();
    
                if(node1 == NULL && node2 == NULL)
                    continue;
                else if(node1 == NULL || node2 == NULL || node1->val != node2->val)  //注意||的特性 不满足才会继续判断
                    return false;
                else {
                    //重点的地方
                    //层序遍历一定要按顺序从左到右来吗? 
                    //可以不需要 我们进行比较的是一行中对称的部分 我们可以讲要比较的放在前俩个位置处
                    Queue.push(node1->left);
                    Queue.push(node2->right);
                    Queue.push(node1->right);
                    Queue.push(node2->left);
                }
            }
            return true;
        }
    };
    
  • 相关阅读:
    JS LeetCode 1423. 可获得的最大点数简单题解
    SpringBoot 学集 (第六章) Docker
    Linux 学记 (第三章)
    Linux 学记 (第二章)
    Linux 学记 (第一章)
    SpringBoot 学集 (第五章) Web开发续
    SpringBoot 学集 (第四章)Web开发
    SpringBoot 学集 (第三章) 日志框架
    SpringBoot 学集 (第二章) 配置文件
    SpringBoot 学集 (第一章)
  • 原文地址:https://www.cnblogs.com/57one/p/14461527.html
Copyright © 2011-2022 走看看