代码随想录算法训练营第60期第三十四天打卡

news2025/5/14 22:57:20

       大家好,我们今天的内容依旧是贪心算法,我们上次的题目主要是围绕多维问题,那种时候我们需要分开讨论,不要一起并发进行很容易顾此失彼,那么我们今天的问题主要是重叠区间问题,又是一种全新的贪心算法思想,这里的题目如果我们之前没有接触过,我们就很难想到今天的解题思路,这里的题目我建议大家可以直接看题解,看完题解后多思考就可以了。

第一题对应力扣编号为452的题目用最少数量的箭引爆气球

        我们一起来看到这一道题目,这一道题目的话考察的应该是重叠区间问题,上面说过了这种思路不好想,那我们就一起来看看这道题目:

        题目其实读一遍大概就了解了我们题目的要求,我们在某一个位置射出弓箭,只要这个气球的直径的范围包含了我这个发射弓箭的位置那我们就可以引爆气球,很明显这是一个重叠区间问题,我们应该用一支弓箭引爆尽可能多的气球,我们一起来看一下这道题目的解题思路,首先局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。贪心算法可以解决这一道题目,

       大家来看我们的示例画出来的图,这是我们排好序的气球,如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。这里是按照气球的起始位置排序,这样我们就应该正序遍历,靠左尽可能让气球重复。如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。这个思想很重要大家可以看到上图,我们是不是要在有重合的气球的右边边界的最小值引一支弓箭,没有重叠的气球一定是不可能一支箭可以引爆的,根据上图可以看出首先第一组重叠气球,一定是需要一个箭,气球3,的左边界大于了 第一组重叠气球的最小右边界,所以再需要一支箭来射气球3了。根据这个思路我们可以尝试写出解题代码:

class Solution {
private:
//这个是我们按照气球的起始位置从小到大排序
    static bool cmp(const vector<int> &a , const vector<int> &b)
    {
        return a[0] < b[0];
    }
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if (points.size() == 0) return 0;
        //排序
        sort(points.begin(), points.end(), cmp);

        int result = 1; // 只要有气球起码就得需要一直弓箭引爆

        for (int i = 1; i < points.size(); ++i)
        {
            //这种情况需要一支箭 气球i和气球i-1不挨着 怎么得使用一直弓箭射爆
            //我需要解释一下这里为什么不加等于,大家看题目x_start <= x <= x_end就可以算作重叠可以引爆
            //也就是我下一个气球的左边界等于上一个气球的右边界的话也算作重叠 
            if (points[i][0] > points[i - 1][1]) result++;
            //更新右边界为什么要更新右边界这个大家注意我们是判断了两个气球是重合的但是与第三个气球是否重合呢?这就得需要更新右边界来比较
            //在遍历的过程中如果我发现目前的最小右边界与第三个气球的左边界不重合了说明我就用一支箭去射爆那两个气球
            else points[i][1] = min(points[i - 1][1], points[i][1]);
        }
        return result;
    }
};

       我给大家写出了详细的注释,大家好好理解,理解我们的区间重叠问题,我们什么时候可以确定我们的两个气球是否重叠,以及什么情况下需要一支新的弓箭,大家仔细理解,我们进入下一道题目。

第二题对应力扣编号为435的题目无重叠区间

       我们来到第二题,很明显一看题目名称我们就知道这应该还是区间重合问题,我们一起来看一下这道题目:

       这道题其实与上一道题目有异曲同工之妙,还是判断两个区间是否重合,但是有一点不一样,就是上一道题目我们如果边界相等的时候我们是可以视为重合的一支箭可以射爆,但这里如果只有一个点重合不能算作是重叠,我们来看一下这道题应该如何解决,我这里给大家讲解我们排序左边界的情况,当然我也给出右边界的情况大家视情况而定,其实左边界我个人感觉比较好理解,主要上一道题我们也是排序的左边界,我们依旧是判断两个区间是否重叠 ,大家注意这里的不重叠的条件是下一个区间的左边界大于等于上一个区间的有边界才是,如果重叠了我们统计重叠的区间,然后更新右边界来判断后续区间是否还是重叠的,大家上一道题目理解的话这道题就不难了,我给出左边界的代码:

class Solution {
private:
//按照左边界排序
    static bool cmp(const vector<int> &a , const vector<int> &b)
    {
        return a[0] < b[0];
    }
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.size() == 0) return 0;
        //按照特定规则排序
        sort(intervals.begin(), intervals.end(), cmp);
        int count = 0; //统计重叠区间的个数
        int end = intervals[0][1];
        for (int i = 1; i < intervals.size(); ++i)
        {
            //表示上来的两个区间并不重合
            //我们就更新右边界无需操作反正都是不重叠的
            if (intervals[i][0] >= end) end = intervals[i][1];
            //这里是重叠
            else
            {
                //更新最小的右边界
                end = min(intervals[i][1], end);
                count++;
            } 
        }
        return count;
    }
};

     我也给出右边界的代码供大家参考:

class Solution {
public:
    // 按照区间右边界排序
    static bool cmp (const vector<int>& a, const vector<int>& b) {
        return a[1] < b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int count = 1; // 记录非交叉区间的个数
        int end = intervals[0][1]; // 记录区间分割点
        for (int i = 1; i < intervals.size(); i++) {
            if (end <= intervals[i][0]) {
                end = intervals[i][1];
                count++;
            }
        }
        return intervals.size() - count;
    }
};

    这道题目就讲解到这里,我们继续进入下一道题目。

第三题对应力扣编号为763的题目划分字母区间

        我们来到今天的最后一题,我相信只要大家把这三道题目弄明白几乎重叠区间问题大家就会有很清楚的了解了,我们一起来看一下今天的最后一道题目:

        题目是什么意思呢?我们要划分为尽可能多的片段,使得原字符串里面的每一个字符都出现在划分好的一个字符串里,而且还不能打乱顺序,使得这些划分好的字符串拼起来还是原字符串,我们需要划分的片段尽可能多,那么应该如何考虑这个问题呢?其实有些朋友可能会觉得这题奇怪我们原则上应该都是求尽可能少的情况,但是这里大家一想你要尽可能少直接不要划分了不就是了,这样肯定题目只能问尽可能多,拿示例一来举例,我出现了字符a,那么我所有的a都要包含进来,我们统计我们a出现的最远位置下标,然后统计过程中b又出现了所以b只能与a分割在一个字符串里面了,然后后来c也出现了我的字符串中,因此c只能与a,b分割在同一个字符串中,最后我们发现a的最远位置就是第一个字符串的长度,接下来e也是一样的道理,还有h都是一样的道理,我们就可以发现我们是需要求出我们每一个字符的最远出现位置的下标,然后我们去求每一个区间长度的时候我们就得用双指针了,然后我们求完一个区间长度我们保存到数组里面,我们讲下一个区间的起始索引交给左指针,最后我们返回result就可以了,我们有了这个思路一起来看一下代码应该如何写:

class Solution {
public:
    vector<int> partitionLabels(string s) {
        //统计每一个字符的最远出现位置
        int hash[27] = {0};
        //如何统计最远出现距离大家注意我的i一直在动这样可以找出最远出现的位置的下标
        for (int i = 0; i < s.size(); ++i)
        {
            hash[s[i] - 'a'] = i;
        }
        int left = 0, right = 0;
        vector<int> result;
        //这个大家要注意eccbbbbdec举例 hash[2] = 9(c) hash[1] = 6(b) hash[4] = 8(e) hash[3] = 7(d)
        // right = 8 right = 9 right = 6 right = 7 right = 8 right = 9 到了最后才会满足i == right
        //我们i == right 就是在寻找区间分界线
        for (int i = 0; i < s.size(); ++i)
        {
            right = max(right, hash[s[i] - 'a']);
            if (i == right)
            {
                result.push_back(right - left + 1);
                //这一个区间找完了接着下一个区间
                left = i + 1;
            }
        }
        return result;
    }
};

       我给大家写好了注释,大家参考一下。

今日总结

          今天的区间重叠问题还是很有趣的,体现了贪心的思想,我们到底是按照左边还是右边排序,这个大家都要思考清楚才可以,今天的分享就到这里了,我们下次再见!

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

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

相关文章

关于IDE的相关知识之二【插件推荐】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于ide插件推荐的相关内容&#xff01…

Axure RP9:列表新增

文章目录 列表新增思路新增按钮操作说明保存新增交互设置列表新增 思路 利用中继器新增行实现列表新增功能 新增按钮操作说明 工具栏中添加新增图标及标签,在图标标签基础上添加热区;对热区添加鼠标单击时交互事件,同步插入如下动作:显示/隐藏动作,设置目标元件为新增窗…

06 mysql之DML

一、什么是DML DML 用于操作数据库中的数据。主要命令包括&#xff1a; INSERT&#xff1a;添加数据SELECT&#xff1a;查询数据UPDATE&#xff1a;修改数据DELETE&#xff1a;删除数据 二、插入数据&#xff08;INSERT&#xff09; 2.1 插入单条记录 -- 插入学生记录&…

【最新版】likeshop连锁点餐系统-PHP版+uniapp前端全开源

一.系统介绍 likeshop外卖点餐系统适用于茶饮类的外卖点餐场景&#xff0c;搭建自己的一点点、奈雪、喜茶点餐系统。 系统基于总部多门店的连锁模式&#xff0c;拥有门店独立管理后台&#xff0c;支持总部定价和门店定价LBS定位点餐&#xff0c;可堂食可外卖。无论运营还是二开…

纯Java实现反向传播算法:零依赖神经网络实战

在深度学习框架泛滥的今天,理解算法底层实现变得愈发重要。反向传播(Backpropagation)作为神经网络训练的基石算法,其实现往往被各种框架封装。本文将突破常规,仅用Java标准库实现完整BP算法,帮助开发者: 1) 深入理解BP数学原理。2) 掌握面向对象的神经网络实现。3) 构建可…

海纳思(Hi3798MV300)机顶盒遇到海思摄像头

海纳思机顶盒遇到海思摄像头&#xff0c;正好家里有个海思Hi3516的摄像头模组开发板&#xff0c;结合机顶盒来做个录像。 准备工作 海纳斯机顶盒摄像机模组两根网线、两个电源、路由器一块64G固态硬盘 摄像机模组和机顶盒都接入路由器的LAN口&#xff0c;确保网络正常通信。 …

Axure应用交互设计:表格跟随菜单移动效果(超长表单)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!本文如有帮助请订阅 Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:表格跟随菜单移动 主要内容:表格交互设计、动态面板嵌套、拖动时事件、移动动作 应用场景…

7系列 之 I/O标准和终端技术

背景 《ug471_7Series_SelectIO.pdf》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。 第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性&#xff0c;并通过大量实例解析了各类标准接口的实现。 第 2 章《SelectIO Logic Resource…

github 上的 CI/CD 的尝试

效果 步骤 新建仓库设置仓库的 page 新建一个 vite 的项目&#xff0c;改一下 vite.config.js 中的 base 工作流 在项目的根目录下新建一个 .github/workflows/ci.yml 文件&#xff0c;然后编辑一下内容 name: Build & Deploy Vue 3 Appon:push:branches: [main]permi…

yup 使用 3 - 利用 meta 实现表单字段与表格列的统一结构配置(适配 React Table)

yup 使用 3 - 利用 meta 实现表单字段与表格列的统一结构配置&#xff08;适配 React Table&#xff09; Categories: Tools Last edited time: May 11, 2025 7:45 PM Status: Done Tags: form validation, schema design, yup 本文介绍如何通过 Yup 的 meta() 字段&#xff0…

【OpenCV】imread函数的简单分析

目录 1.imread()1.1 imread()1.2 imread_()1.2.1 查找解码器&#xff08;findDecoder&#xff09;1.2.2 读取数据头&#xff08;JpegDecoder-->readHeader&#xff09;1.2.2.1 初始化错误信息&#xff08;jpeg_std_error&#xff09;1.2.2.2 创建jpeg解压缩对象&#xff08;…

【Linux实践系列】:进程间通信:万字详解共享内存实现通信

&#x1f525; 本文专栏&#xff1a;Linux Linux实践项目 &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; 人生就像一场马拉松&#xff0c;重要的不是起点&#xff0c;而是坚持到终点的勇气 ★★★ 本文前置知识&#xff1a; …

【笔记】BCEWithLogitsLoss

工作原理 BCEWithLogitsLoss 是 PyTorch 中的一个损失函数&#xff0c;用于二分类问题。 它结合了 Sigmoid 激活函数和二元交叉熵&#xff08;Binary Cross Entropy, BCE&#xff09;损失在一个类中。 这不仅简化了代码&#xff0c;而且通过数值稳定性优化提高了模型训练的效…

关于Go语言的开发环境的搭建

1.Go开发环境的搭建 其实对于GO语言的这个开发环境的搭建的过程&#xff0c;类似于java的开发环境搭建&#xff0c;我们都是需要去安装这个开发工具包的&#xff0c;也就是俗称的这个SDK&#xff0c;他是对于我们的程序进行编译的&#xff0c;不然我们写的这个代码也是跑不起来…

Flutter PIP 插件 ---- 为iOS 重构PipController, Demo界面,更好的体验

接上文 Flutter PIP 插件 ---- 新增PipActivity&#xff0c;Android 11以下支持自动进入PIP Mode 项目地址 PIP&#xff0c; pub.dev也已经同步发布 pip 0.0.3&#xff0c;你的加星和点赞&#xff0c;将是我继续改进最大的动力 在之前的界面设计中&#xff0c;还原动画等体验一…

数据库管理-第325期 ADG Failover后该做啥(20250513)

数据库管理325期 2025-05-13 数据库管理-第325期 ADG Failover后该做啥&#xff08;20250513&#xff09;1 故障处置2 恢复原主库3 其他操作总结 数据库管理-第325期 ADG Failover后该做啥&#xff08;20250513&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&a…

SQLi-Labs 第21-24关

Less-21 http://127.0.0.1/sqli-labs/Less-21/ 1&#xff0c;抓个请求包看看 分析分析cookie被base64URL编码了&#xff0c;解码之后就是admin 2&#xff0c;那么这个网站的漏洞利用方式也是和Less-20关一样的&#xff0c;只是攻击语句要先base64编码&#xff0c;再URL编码&…

PVE WIN10直通无线网卡蓝牙

在 Proxmox VE (PVE) 中直通 Intel AC3165 无线网卡的 **蓝牙模块**&#xff08;通常属于 USB 设备&#xff0c;而非 PCIe 设备&#xff09;需要特殊处理&#xff0c;因为它的蓝牙部分通常通过 USB 连接&#xff0c;而 Wi-Fi 部分才是 PCIe 设备。以下是详细步骤&#xff1a; …

第六节第二部分:抽象类的应用-模板方法设计模式

模板方法设计模式的写法 建议使用final关键字修饰模板方法 总结 代码&#xff1a; People(父类抽象类) package com.Abstract3; public abstract class People {/*设计模板方法设计模式* 1.定义一个模板方法出来*/public final void write(){System.out.println("\t\t\t…

在另一个省发布抖音作品,IP属地会随之变化吗?

你是否曾有过这样的疑惑&#xff1a;出差旅游时在外地发布了一条抖音视频&#xff0c;评论区突然冒出“IP怎么显示xx省了&#xff1f;”的提问&#xff1f;随着各大社交平台上线“IP属地”功能&#xff0c;用户的地理位置标识成为公开信息&#xff0c;而属地显示的“灵敏性”也…