当前位置: 首页 > article >正文

力扣做题记录 (二叉树)

二叉树

打算先来了解二叉树基础,都是简单题,目的是熟悉代码格式和解题基础思路。

1、二叉树最大深度

二叉树最大深度
在这里插入图片描述

方法一、深度搜索

直接用原函数做递归,比较简单

/**
 * 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:
    int maxDepth(TreeNode* root) {
        if(root ==nullptr)return 0;
        return max(maxDepth(root->left), maxDepth(root->right))+1;
    }
};

方法二、广度搜索

  • 利用queue来存储每一层的节点
  • 每层次循环是当前queue的长度,用一个数来记录,一般是2的次方,然后再将新的数放置queue末尾。
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==nullptr)return 0;
        queue<TreeNode*> Q;
        Q.push(root);
        int depth = 0;
        while(!Q.empty()){
            int sz=Q.size();
            while(sz>0){
                TreeNode* node= Q.front();
                Q.pop();
                if(node->left)Q.push(node->left);
                if(node->right)Q.push(node->right);
                sz-=1;
            }
            depth+=1;
        }
        return depth;
    }
};

2、相同的树

相同的树

在这里插入图片描述

方法一、前序遍历比较

这是自己写的,思路是确定可以用递归,这个是深度搜索
然后先判断节点存在,再判断是否正确

/**
 * 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 isSameTree(TreeNode* p, TreeNode* q) {
        bool a=true,b=true;
        if(p==nullptr&&q==nullptr)return true;
        else if(p!=nullptr&&q==nullptr)return false;
        else if(p==nullptr&&q!=nullptr)return false;
        else{
            if(p->val!=q->val)return false;
            a=isSameTree(p->left,q->left);
            b=isSameTree(p->right,q->right);
        }
        if(a==false||b==false)return false;
        else return true;
    }
};

方法二、广度搜索

来自官方题解中的一种有点复杂。

class Solution {  
public:  
    // 检查两棵二叉树是否相同  
    bool isSameTree(TreeNode* p, TreeNode* q) {  
        // 如果两棵树都为空,返回 true  
        if (p == nullptr && q == nullptr) {  
            return true;  
        }   
        // 如果一棵树为空而另一棵树不为空,返回 false  
        else if (p == nullptr || q == nullptr) {  
            return false;  
        }  

        // 创建两个队列用于广度优先搜索(BFS)  
        queue<TreeNode*> queue1, queue2;  
        queue1.push(p); // 将第一个树的根节点入队  
        queue2.push(q); // 将第二个树的根节点入队  

        // 当两个队列都不为空时,继续比较  
        while (!queue1.empty() && !queue2.empty()) {  
            // 取出两个队列的前端节点进行比较  
            auto node1 = queue1.front();  
            queue1.pop();  
            auto node2 = queue2.front();  
            queue2.pop();  

            // 比较两个节点的值  
            if (node1->val != node2->val) {  
                return false; // 值不相同,则树不相同  
            }  

            // 获取当前节点的左右子节点  
            auto left1 = node1->left, right1 = node1->right;  
            auto left2 = node2->left, right2 = node2->right;  

            // 检查左右子节点是否存在不一致  
            if ((left1 == nullptr) ^ (left2 == nullptr)) {  
                return false; // 只有一棵树有左子节点  
            }  
            if ((right1 == nullptr) ^ (right2 == nullptr)) {  
                return false; // 只有一棵树有右子节点  
            }  

            // 如果左右子节点存在,则将其加入队列中  
            if (left1 != nullptr) {  
                queue1.push(left1); // 将第一个树的左子节点添加到队列  
            }  
            if (right1 != nullptr) {  
                queue1.push(right1); // 将第一个树的右子节点添加到队列  
            }  
            if (left2 != nullptr) {  
                queue2.push(left2); // 将第二个树的左子节点添加到队列  
            }  
            if (right2 != nullptr) {  
                queue2.push(right2); // 将第二个树的右子节点添加到队列  
            }  
        }  

        // 返回两个队列是否都为空(即两棵树的结构是否相同)  
        return queue1.empty() && queue2.empty();  
    }  
};

3、翻转二叉树

翻转二叉树

在这里插入图片描述

方法一、

用递归找到最下方的左右子树,直接更换节点而不是值

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if(root==nullptr){
            return nullptr;
        }
        TreeNode *left=invertTree(root->left);
        TreeNode *right=invertTree(root->right);
        root->left=right;
        root->right=left;
        return root;
    }
};

4、对称二叉树

101.对称二叉树
在这里插入图片描述

方法一、广度匹配

也就是迭代求解,下面是我自己写的复杂的代码,因为本能觉得可以把每一层,存储为一个vector,然后再综合比较。但是实现起来略显复杂

/**
 * 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*> tree_level;
        vector<int> num_level;
        vector<int> num_level_re;
        int level=1;
        if(root->left==nullptr&&root->right==nullptr)return true;
        else if(root->left!=nullptr&&root->right!=nullptr){level=1;}
        else return false;
        tree_level.push(root->left);
        num_level.push_back(root->left->val);
        tree_level.push(root->right);
        num_level.push_back(root->right->val);
        while(tree_level.size()!=0){
            num_level_re=num_level;
            reverse(num_level_re.begin(),num_level_re.end());
            for(int i=0;i<num_level.size();i++){
                if(num_level[i]==num_level_re[i])continue;
                else return false;
            }
            num_level.clear();
            num_level_re.clear();
            // 把每层都节点和元素加入
            int level1 = tree_level.size();
            while(level1>0){
                TreeNode* root_now;
                root_now = tree_level.front();
                tree_level.pop();
                if(root_now->left!=nullptr){tree_level.push(root_now->left);num_level.push_back(root_now->left->val);}
                else num_level.push_back(-1);
                if(root_now->right!=nullptr){tree_level.push(root_now->right);num_level.push_back(root_now->right->val);}
                else num_level.push_back(-1);
                level1--;
            }
            // 判断每层不能为奇数
            if(tree_level.size()%2!=0)return false;  
            level++;
        }
        return true;
    }
};

方法二、精简迭代法

其思路是:特地写一个辅助函数,可以同时输入左右子树,这样更加方便做迭代

class Solution {
public:
    bool check(TreeNode *u, TreeNode *v) {
        queue <TreeNode*> q;
        q.push(u); q.push(v);
        while (!q.empty()) {
            u = q.front(); q.pop();
            v = q.front(); q.pop();
            if (!u && !v) continue;
            if ((!u || !v) || (u->val != v->val)) return false;

            q.push(u->left); 
            q.push(v->right);

            q.push(u->right); 
            q.push(v->left);
        }
        return true;
    }

    bool isSymmetric(TreeNode* root) {
        return check(root, root);
    }
};

方法三、递归法

比较难想到,下面是解释
也需要辅助函数, 然后最左的和最右的分别组成对对比

class Solution {
public:
    // 辅助函数:检查两个子树是否对称
    bool check(TreeNode *leftNode, TreeNode *rightNode) {
        // 情况 1:两个节点都为空
        if (leftNode == nullptr && rightNode == nullptr) {
            return true; // 空节点是对称的
        }
        // 情况 2:其中一个节点为空,另一个不为空
        if (leftNode == nullptr || rightNode == nullptr) {
            return false; // 不对称
        }
        // 情况 3:两个节点的值不相等
        if (leftNode->val != rightNode->val) {
            return false; // 不对称
        }
        // 递归检查:
        // 1. 左子树的左节点和右子树的右节点是否对称
        // 2. 左子树的右节点和右子树的左节点是否对称
        bool isOuterSymetric = check(leftNode->left, rightNode->right);  // 检查外层
        bool isInnerSymetric = check(leftNode->right, rightNode->left); // 检查内层
        // 只有外层和内层都对称,整个树才对称
        return isOuterSymetric && isInnerSymetric;
    }
    // 主函数:判断二叉树是否对称
    bool isSymmetric(TreeNode* root) {
        // 如果根节点为空,直接返回 true(空树是对称的)
        if (root == nullptr) {
            return true;
        }
        // 检查左子树和右子树是否对称
        return check(root->left, root->right);
    }
};

http://www.kler.cn/a/549566.html

相关文章:

  • 使用redis实现与flink窗口同样的消息聚合处理效果
  • GitLab CI/CD 的配置详解:从零开始使用 .gitlab-ci.yml 文件
  • BEV:车轮接地点车辆修正3D框位置精度
  • OpenCV机器学习(2)提升算法类cv::ml::Boost
  • 第25周Java主流框架实战-springboot入门 4.配置详解
  • 第 16 天:游戏 UI(UMG)开发,打造主菜单 血条!
  • ​矩阵元素的“鞍点”​
  • newgrp docker需要每次刷新问题
  • 使用bitnamiredis-sentinel部署Redis 哨兵模式
  • Android 13 通过修改 AOSP 禁用扬声器
  • 练习题 - DRF 3.x Parsers 解析器使用示例和配置方法
  • openGauss 3.0 数据库在线实训课程16:学习逻辑结构:表管理4
  • R 语言科研绘图第 24 期 --- 直方图-高亮
  • Vue CLI 配置与插件
  • 机器学习:集成学习和随机森林
  • 解锁二进制数组:JS、TS、ArkTS 解析
  • MySQL DELETE 语句
  • WPS的AI助手进化跟踪(灵犀+插件)
  • 人工智能 - 大脑神经网络与机器神经网络的区别
  • Deepseek R1模型本地化部署与API实战指南:释放企业级AI生产力