leetcode刷题详解六

news2025/1/12 23:30:40
124. 二叉树中的最大路径和

这个解析很好

所有树的题目,都想成一颗只有根、左节点、右节点 的小树。然后一颗颗小树构成整棵大树,所以只需要考虑这颗小树即可。接下来分情况, 按照题意:一颗三个节点的小树的结果只可能有如下6种情况:

  1. 根 + 左 + 右
  2. 根 + 左
  3. 根 + 右

只有 2,3,4 可以向上累加,而1,5,6不可以累加(这个很好想,情况1向上累加的话,必然出现分叉,情况5和6直接就跟上面的树枝断开的,没法累加),所以我们找一个全局变量存储 1,5,6这三种不可累加的最大值, 另一方面咱们用遍历树的方法求2,3,4这三种可以累加的情况。 最后把两类情况得到的最大值再取一个最大值即可。

class Solution {
public:
    int case1 = INT_MIN;
    int maxPathSum(TreeNode* root) {
        int case2 = dfs(root);
        return max(case1, case2);
    }
    int dfs(TreeNode* root){
        if(!root){
            //注意,不能return0,-3这个例子就出粗哦了
            //因为节点会比0更小
            return -1000;
        }
        int left = dfs(root->left);
        int right = dfs(root->right);
        //一下三种情况无法回溯给父节点收益,所以只能全局变量Case1记录一下。
        case1 = max(root->val + left + right, case1);
        case1 = max(case1, left);
        case1 = max(case1, right);
        int case2 = root->val;
        case2 = max(case2, root->val + left);
        case2 = max(case2, root->val + right);
        return case2;
    }
};
236. 二叉树的最近公共祖先

详细解释

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if(!root || root == q || root == p){
        return root;
    }
    TreeNode* left = lowestCommonAncestor(root->left, p, q);
    TreeNode* right = lowestCommonAncestor(root->right, p, q);
    if(!left){
        return right;
    }
    if(!right){
        return left;
    }
    if(!left && !right){
        return nullptr;
    }
    return root;
}
102. 二叉树的层序遍历

思路:本质上还是层序遍历,只不过要循环一下每一层的节点数而已

/**
 * 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:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        queue<TreeNode* > m_queue;
        if(root){
            m_queue.push(root);
        }
        while(!m_queue.empty()){
            int len = m_queue.size();
            vector<int> rec;
            for(int i = 0; i < len; i++){
                TreeNode* tmp = m_queue.front();
                rec.push_back(tmp->val);
                m_queue.pop();
                if(tmp->left){
                    m_queue.push(tmp->left);
                }
                if(tmp->right){
                    m_queue.push(tmp->right);
                }
            }
            result.push_back(rec);
        }
        return result;
    }
};
222. Count Complete Tree Nodes

这个题就是完全二叉树的性质,给一个二叉树,然后判断有几个节点,下图很能说明情况:

222.完全二叉树的节点个数

如果是满二叉树,直接就是 2 n − 1 2^n-1 2n1,如果不是满二叉树,那么就往下递归呗

int countNodes(TreeNode* root) {
    if(!root){
        return 0;
    }
    int left_height = 0;
    int right_height = 0;
    TreeNode* left_node = root->left;
    TreeNode* right_node = root->right;
    while(left_node){
        left_node = left_node->left;
        left_height++;
    }
    while(right_node){
        right_node = right_node->right;
        right_height++;
    }
    if(left_height == right_height){
        return (2<<left_height) - 1;
    }
    return countNodes(root->left) + countNodes(root->right) + 1; //1是根节点
}

二叉搜索树BST

700. 二叉搜索树中的搜索
TreeNode* searchBST(TreeNode* root, int val) {
        if(!root){
            return nullptr;
        }
        if(root->val == val){
            return root;
        }
        else if(root->val < val){
            return searchBST(root->right,val);
        }
        else if(root->val > val){
            return searchBST(root->left,val);
        }
        return nullptr;
    }
  • 知识点

    递归返回函数名称有什么需要注意的?

  • 数据结构

    BST数增山查改由于本身性质的原因,和普通二叉树肯定不一样。

    因此本身是有框架的,如下

    void BST(TreeNode root, int target) {    
        if (root.val == target)        // 找到目标,做点什么    
            if (root.val < target)         
                BST(root.right, target);    
        if (root.val > target)       
            BST(root.left, target);
    }
    
230. 二叉搜索树中第K小的元素

这题是BST(二叉搜索树)

思路一: BST中序遍历就是升序排序,因此可以用中序遍历做,但是时间复杂度是O(n),有点大,不太行

思路二:参考链接,题目中给定的数据结构无法实现思路二

vector<int> vec;
    int kthSmallest(TreeNode* root, int k) {
        reverse_tree(root);
        return vec[k-1];
    }
    void reverse_tree(TreeNode* root){
        if(!root){
            return ;
        }
        reverse_tree(root->left);
        vec.push_back(root->val);
        reverse_tree(root->right);
        return ;
    }
  • 题目细节

    由于原函数返回值是int,不适合递归,因此需要重新新一个辅助函数来完成树的递归。

  • 涉及的数据结构

    • BST(二叉搜索树)是一个有序的基础树,avl、rb_tree是在其基础上而来的,是自平衡的树,提供logN级别的增山查改效率

    • BST树的特点:

      1. 对于 BST 的每一个节点node,左子树节点的值都比node的值要小,右子树节点的值都比node的值大。
      2. 对于 BST 的每一个节点node,左子树节点的值都比node的值要小,右子树节点的值都比node的值大。
    • BST树中序遍历就是升序排序。

538. 把二叉搜索树转换为累加树

这道题真的真的特别的巧!!!!!

本质上还是二叉树的中序遍历,但是正常是升序。

我们需要逆序的节点顺序,因此先右后左不就行了!

int sum = 0;
TreeNode* convertBST(TreeNode* root) {
    if(!root){
        return nullptr;
    }
    convertBST(root->right);
    root->val = sum + root->val;
    sum = root->val;
    convertBST(root->left);
}

这道题就是巧!没别的!

98. 验证二叉搜索树

思路一:中序遍历是升序,别忘了!

思路二:递归,每一个根节点左子树也是BST,右子树也是BST

思路二有坑,主要在于对于每一个节点root,我们可能会写成判断root节点的左节点小于和右节点大于。这是错误的,因为BST树保证了必须是左节点为根节点的数也是BST,右节点同理

思路一代码:

long long temp = (long long)INT_MIN-1;
    bool isValidBST(TreeNode* root) {
        if(!root){
            return true;
        }
        if(!isValidBST(root->left)){
         return false;   
        }
        if(temp >= root->val){
            return false;
        }
        temp = root->val;
        if(!isValidBST(root->right)){
            return false;   
        }
        return true;
    }

​ 上述代码可能不好理解,换一种写法,

long long temp = (long long)INT_MIN-1;
    bool isValidBST(TreeNode* root) {
        if(!root){
            return true;
        }
        bool left =  isValidBST(root->left);
        if(temp >= root->val){
            return false;
        }
        temp = root->val;
        bool right =  isValidBST(root->right);
        return left && right;
    }
  • 本题需要注意的点

    • 老生常谈的问题,在做递归的时候return不知道该怎么写。这道题函数的返回值是布尔类型,所以你也要写布尔类型的返回值,但是如何return就是一门学问了!

    • 注意看代码long long temp = (long long)INT_MIN-1;

      这样写是因为有一个测试用例,[-2147483648] 这个值就是INT_MIN所以,我们最小值必须使用比INT_MIN小的才行,所以int越界了,就用long long ,不要忘记强制转换!

701. 二叉搜索树中的插入操作
TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(!root){
            //二叉查找树肯定是放在根节点上!!!
            return new TreeNode(val);
        }
        if(root->val < val){
            root->right = insertIntoBST(root->right, val);
        }
        else if(root->val > val){
            root->left = insertIntoBST(root->left, val);
        }
        return root;
    }
450. 删除二叉搜索树中的节点

第二次写这道题的时候必须记录一下:在二叉树的递归中,如果你需要一个dummy节点,那么这个dummy节点其实就在root->left = delete(root->left)中,此时这个root就是前置节点!!!这一点一定要记好了!!

/**
 * 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* deleteNode(TreeNode* root, int key) {
        if(!root){
            return nullptr;
        }
        if(root->val == key){
            if(!root->left && !root->right){
                return nullptr;
            }
            else if(!root->left){
                return root->right;
            }
            else if(!root->right){
                return root->left;
            }else{
                TreeNode* tmp  = root->right;
                TreeNode* dummy = root;
                while(tmp->left){
                    dummy = tmp;
                    tmp = tmp->left;
                }
                cout<<"dummy->val"<<dummy->val<<endl;
                cout<<"tmp->val"<<tmp->val<<endl;
                root->val = tmp->val;
                //这点容易错 草他妈,要判断dummy是不是原来的节点
                if(dummy == root){
                    dummy->right = tmp->right;
                }
                else if(dummy != root){
                   dummy->left = tmp->right;
                }
            }
        }
        if(root->val > key){
            root->left = deleteNode(root->left, key);
        }
        if(root->val < key){
            root->right = deleteNode(root->right, key);
        }
        return root;
    }
};
  • 涉及到的数据结构

    这道题主要涉及二叉搜索树BST的删除问题。这个问题我想了三个小时,难点在于节点的删除的代码上

    BST节点删除要分成三种情况

    • 第一种

      当被删除的节点是叶子节点,即无左孩子也无右孩子时,直接删除即可,简单

    • 第二种

      当被删除的节点只包含左孩子或者右孩子时,删除也很简单

    • 第三种

      当被删除的节点同时包含左孩子或者右孩子。我们从被删除节点的右节点为起点,往左子树上找最后一个节点,画个图就知道了。

      然后把这个几点的值和被删除节点的互换,把该节点删掉就行。

96. 不同的二叉搜索树

举个例子,比如给算法输入n = 5,也就是说用{1,2,3,4,5}这些数字去构造 BST。

根据 BST 的特性,根节点的左子树都比根节点的值小,右子树的值都比根节点的值大。

所以如果固定3作为根节点,左子树节点就是{1,2}的组合,右子树就是{4,5}的组合。

左子树的组合数和右子树的组合数乘积就是3作为根节点时的 BST 个数。

这道题动态规划和递归都能写

  • 动态规划

    int numTrees(int n) {
           vector<int> vec(n+1, 0);
           vec[0] = 1;
           vec[1] = 1;
           for(int i = 2; i < n + 1; i++){
               for(int j = 1; j <= i; j++){
                    vec[i] += vec[j - 1] * vec[i - j]; 
               }
               cout<<vec[i]<<endl;
           }
           return  vec[n];
        } 
    

    注意,当有0个数的时候,可以构成一个BST,因为空树也是!!!!

  • 递归(难)

  • 迭代—不能用!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1259703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV完结篇——计算机视觉(人脸识别 || 车牌识别)

文章目录 Haar人脸识别方法Haar识别眼鼻口HaarTesseract进行车牌识别深度学习基础知识dnn实现图像分类 Haar人脸识别方法 scaleFactor调整哈尔级联器的人脸选框使其能框住人脸 官方教程指路 每个特征都是通过从黑色矩形下的像素总和减去白色矩形下的像素总和获得的单个值 级…

94.STM32外部中断

目录 1.什么是 NVIC&#xff1f; 2.NVIC寄存器 3.中断优先级 4.NVIC的配置 设置中断分组​编辑 配置某一个中断的优先级 5.什么是EXTI 6.EXTI和NVIC之间的关系 7.SYSCFG 的介绍 1.什么是 NVIC&#xff1f; NVIC是一种中断控制器&#xff0c;主要用于处理 ARM Cort…

如何将mobi、awz3、epub格式转化为pdf

偶然之间有个需求就是网上下载了一些书籍的格式没法打开看&#xff0c;或者是想把kindle的书籍转换成pdf 那么经过一番折腾找到了两个可以用的工具站分享给大家&#xff0c;有需要的可是尝试下&#xff0c;小编这边测试了可以用&#xff0c;就是下载的时候慢的一匹。。。 第一…

【C++】类型转换 ④ ( 子类 和 父类 之间的类型转换 - 动态类型转换 dynamic_cast )

文章目录 一、子类 和 父类 之间的类型转换 - 动态类型转换 dynamic_cast1、构造父类和子类2、子类 和 父类 之间的类型转换 - 隐式类型转换3、子类 和 父类 之间的类型转换 - 静态类型转换 static_cast4、子类 和 父类 之间的类型转换 - 重新解释类型转换 reinterpret_cast5、…

时间序列预测实战(二十)自研注意力机制Attention-LSTM进行多元预测(结果可视化,自研结构)

一、本文介绍 本文给大家带来的是我利用我自研的结构进行Attention-LSTM进行时间序列预测&#xff0c;该结构是我专门为新手和刚入门的读者设计&#xff0c;包括结果可视化、支持单元预测、多元预测、模型拟合效果检测、预测未知数据、以及滚动长期预测&#xff0c;大家不仅可…

2023-2024-1-高级语言程序设计-字符数组

7-1 凯撒密码 为了防止信息被别人轻易窃取&#xff0c;需要把电码明文通过加密方式变换成为密文。输入一个以回车符为结束标志的字符串&#xff08;少于80个字符&#xff09;&#xff0c;再输入一个整数offset&#xff0c;用凯撒密码将其加密后输出。恺撒密码是一种简单的替换…

DIO算法

歌声和语音声带振动周期的快速可靠F0估计方法 原文题目&#xff1a; Fast and reliable F0 estimation method based on the period extraction of vocal fold vibration of singing voice and speech 发表在&#xff1a; AES 35TH INTERNATIONAL CONFERENCE, London, UK, 200…

【RLChina2023】CCF 苏州 记录

目录 RLChina介绍主旨报告专题报告智能体学习理论(专题一)智能体决策与规划(专题二)智能体框架、体系结构与训练系统(专题六)基于大语言模型的具身智能体与机器人研究 (专题八)教学报告——强化学习入门特别论坛——智能体和多智能体艺术的探索会议照片RLChina介绍 RLC…

什么是迁移学习

1 迁移学习概述 迁移学习&#xff08;Transfer Learning&#xff09;是机器学习中的一种方法&#xff0c;它允许模型将从一个任务中学到的知识应用到另一个相关的任务中。这种方法在数据稀缺的情况下尤为有用&#xff0c;因为它减少了对大量标记数据的需求。迁移学习已成为深度…

Failed to load resource: the server responded with a status of 404 ()

路径问题&#xff1a; 路径省略前面的http://localhost:8080/ 就行了。

OSG粒子系统与阴影 - ​​​​​​​阴影shadow(7)

OSG阴影 在虚拟现实仿真中&#xff0c;为了真实地模拟自然效果&#xff0c;阴影效果是不可缺少的&#xff0c;它对一个场景的真实性是非常重要的。在游戏或仿真中&#xff0c;一个高效的阴影往往能够提供非常强悍的视觉真实感。 osgShadow库 在OSG中专门定义了一个名字空间osg…

ShowWeb-浏览器插件:可视化元素路径查看器

ShowWeb&#x1f47b;&#xff1a;可视化元素路径查看器适配【谷歌】【Edge】 每次写前端最烦的就是一层一层找元素&#xff0c;又臭又长。所以我开发了一个小插件来缓解这个问题&#xff0c;这个插件可以输出整个路径&#xff0c;并把最后元素的内容输出方便查看&#xff0c;…

docker基础快速入门:基础命令、网络、docker compose工具

docker基础命令快速入门 目录 docker基本命令docker 网络docker compose Docker介绍 Docker是一个虚拟环境容器&#xff0c;可以将你的开发环境、代码、配置文件等一并打包到这个容器中&#xff0c;并发布和应用到任意平台中。 Docker的三个概念 镜像 Docker镜像是一个特…

Java飞翔的小鸟

一、项目分析 创建一个窗口和画板&#xff0c;把画板放到窗口上&#xff0c;在画板上绘画图片 &#xff08;2&#xff09;让小鸟在画面中动起来&#xff0c;可以上下飞 &#xff08;3&#xff09;让地面和管道动起来 &#xff08;4&#xff09;碰撞检测 &#xff08;5&#xf…

2023信息技术应用创新论坛|云轴科技ZStack分享云原生超融合在智慧交通的应用

11月25日&#xff0c;2023信息技术应用创新论坛在常州开幕。江苏省工业和信息化厅副厅长池宇、中国电子工业标准化技术协会理事长胡燕、常州市常务副市长李林等领导出席论坛并致辞。中国工程院院士郑纬民出席并作主题报告。来自产学研用金等各界的千余名代表参加本次论坛。 在“…

UE5 - 虚幻引擎各模块流程图

来自虚幻官方的一些资料&#xff0c;分享一下&#xff1b; 一些模块的流程图&#xff0c;比如动画模块&#xff1a; 或角色相关流程&#xff1a; 由于图片比较大&#xff0c;上传到了网络&#xff0c;可自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1BQ2KiuP08c…

MATLAB的rvctools工具箱熟悉运动学【机械臂机器人示例】

1、rvctools下载安装 rvctools下载地址&#xff1a;rvctools下载 截图如下&#xff0c;点击红色箭头指示的“Download Shared Folder” 即可下载 下载之后进行解压&#xff0c;解压到D:\MATLAB\toolbox这个工具箱目录&#xff0c;这个安装路径根据自己的情况来选择&#xff0c…

【华为OD】统一考试C卷真题 100%通过: 传递悄悄话 二叉树遍历 C/C++实现

目录 题目描述&#xff1a; 示例1 解题思路&#xff1a; 代码实现&#xff1a; 题目描述&#xff1a; 给定一个二叉树&#xff0c;每个节点上站着一个人&#xff0c;节点数字表示父节点到该节点传递悄悄话需要花费的时间。 初始时&#xff0c;根节点所在位置的人有一个悄悄…

中通快递查询入口,根据物流更新量筛选出需要的单号记录

批量中通快递单号的物流信息&#xff0c;根据物流更新量将需要的单号记录筛选出来。 所需工具&#xff1a; 一个【快递批量查询高手】软件 中通快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;并登录 步骤2&#xff1a;点击主…

代码随想录算法训练营第六十天|84. 柱状图中最大的矩形

84. 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释…