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

力扣做题记录 (二叉树)

二叉树

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

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);
    }
};

相关文章:

  • MySQL 插入替换语句(replace into statement)
  • 配置Open-R1,评测第三方蒸馏模型的性能1
  • 淘宝商品评论API接口概述,json数据示例返回
  • 高等代数笔记—欧几里得空间、双线性函数
  • Java运维实战:问题定位-CPU突增排查
  • C++ Primer 函数匹配
  • 车载音频架构图详解(精简)
  • 2025-02-16 学习记录--C/C++-PTA 7-20 打印九九口诀表
  • C++笔记之类型大小、变量大小,vector与string在栈上内存、堆上内存和总内存的关系
  • PHP培训机构教务管理系统小程序
  • 八大排序——简单选择排序
  • 提示工程实现数据质量评估
  • matlab飞行姿态pid控制
  • 工业级推荐系统冷启动解决方案:基于元迁移学习与动态知识图谱的混合架构设计与实践
  • 【go语言规范】Gopherfest 2015 | Go Proverbs with Rob Pike的 总结
  • 深入理解 Shell 脚本执行方式:`source`、`./xx.sh`、`bash xx.sh` 和 `sh xx.sh`
  • 顺序表(C)
  • centos部署open-webui
  • MybatisMybatisPllus公共字段填充与配置逻辑删除
  • 【第12章:深度学习与伦理、隐私—12.1 AI伦理原则与偏见检测的方法与实践】
  • 2025上海车展圆满闭幕,共接待海内外观众101万人次
  • 我国首个少数民族非遗纺织类国标正式实施
  • 上海与世界|黄菊与上海建设中国式全球城市
  • 证监会:坚决拥护党中央对王建军进行纪律审查和监察调查的决定
  • 王受文已任中华全国工商业联合会领导班子成员
  • 揭秘神舟十九号返回舱“软着陆”关键:4台发动机10毫秒内同时点火