代码随想录算法训练营第三十六天| LeetCode 435. 无重叠区间、763.划分字母区间、56. 合并区间

news2024/11/25 22:28:42

一、LeetCode 435. 无重叠区间

题目链接/文章讲解/视频讲解:https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html

状态:已解决

1.思路 

        本题的局部最优是尽量移除与某个区间重叠的其他区间,全局最优是移除的区间数最少,局部最优可以推出全局最优,因此可以贪心。如图

        这种情况当然就只移除第二个区间,这样就刚好使得剩下的区间不重叠。 

        这种情况无论如何都至少要移除两个区间。因此对于k个重叠区间,最少都需要移除(k-1)个区间,才能使得剩余区间并不重叠。

        因此,此题和452题思路都一致,就是寻找重叠区间,只是这题重叠区间要保留一份,而452题是重叠区间用一只箭射掉,二者统计得到的数量是一致的。故求未重叠的区间的数量的代码是一模一样的,本题再用所有区间的数量-未重叠区间的数量,就能得到要移除的重叠区间的数量。

2.代码实现

class Solution {
public:
    static bool cmp(const vector<int>& v1, const vector<int>& v2){
    //第一元素相等时,再比较第二元素
        if (v1[0] == v2[0])
            return v1[1] < v2[1];
        return v1[0] < v2[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int num = 1;
        sort(intervals.begin(),intervals.end(),cmp);
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]>=intervals[i-1][1]){
                num++;
            }else{
                intervals[i][1] = min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return intervals.size()-num;//相当于452题多出了一步求移除区间的数量,二题是对称的
    }
};

二、 763.划分字母区间

题目链接/文章讲解/视频讲解:https://programmercarl.com/0763.%E5%88%92%E5%88%86%E5%AD%97%E6%AF%8D%E5%8C%BA%E9%97%B4.html

状态:已解决

1.思路 

        一般说到分割字符串问题,我们下意识就想到回溯算法,但回溯算法效率较低,一般还是优先采用效率较高的算法。此题就可以不用回溯。

        此题要求同一字母最多出现在同一个片段中,那么如何保证某个字母只出现在同一个片段中呢?很简单,我们在划分片段的时候,就选取这个字母第一次出现的位置和它最远出现的位置,这样划分出来的其他片段就不会存在该字母了。如果在这个划分区间内,有其他字母出现,那么这个片段的右边界就不一定取这个字母的最远位置了,而是取这个字母开始位置到这个字母的最远位置之间,所有字母的最远位置的最大值。如图:

        此时取得是a的起始位置和c的最远位置。

        想明白这个点,接下来就很好处理了,可以分为如下两步:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

2.代码实现

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27]={0};
        vector<int> result;
        for(int i=0;i<s.size();i++)
        {
            hash[s[i]-'a'] = i;
        }
        int left=0,right=0;
        for(int i=0;i<s.size();i++){
            right = max(hash[s[i]-'a'],right);
            if(i == right){
                result.push_back(right-left+1);
                left = i + 1;
            }
        }
        return result;
    }
};

时间复杂度:O(n)

空间复杂度:O(1) 

三、56. 合并区间

题目链接/文章讲解/视频讲解:https://programmercarl.com/0056.%E5%90%88%E5%B9%B6%E5%8C%BA%E9%97%B4.html

状态:已解决

1.思路 

        我想的比较直接,这道题很明显还是一个找重叠区间的题,只不过前面的题都是计算去掉重叠区间后未重叠区间的数量,或者是,数轴上分开的区间的数量;而此题是要求你找到重叠区间后做合并操作。怎么合并?我的想法是延申上题的做法,用一个变量来记录每次重叠的左边界,然后找到重叠的区间(intervals[i][0] <= intervals[i-1][1]),就合并区间(具体操作是取intervals[i][1] 和intervals[i-1][1]中的最大值,即更新区间右边界)。

2.代码实现

class Solution {
public:
    static bool cmp(const vector<int>& v1, const vector<int>& v2){
    //第一元素相等时,再比较第二元素
        if (v1[0] == v2[0])
            return v1[1] < v2[1];
        return v1[0] <= v2[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if(intervals.size()==1) return intervals;
        sort(intervals.begin(),intervals.end(),cmp);
        int left = intervals[0][0];
        vector<vector<int>> result;
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]>intervals[i-1][1]){//与前面区间不重叠
                result.push_back({left,intervals[i-1][1]});//将前面的重叠区间存入结果数组
                left = intervals[i][0];//更新新的重叠区间的左边界
            }
            else{
                intervals[i][1] = max(intervals[i][1],intervals[i-1][1]);//合并重叠区间,也就是更新右边界
            }
        }
        result.push_back({left,max(intervals[intervals.size()-1][1],intervals[intervals.size()-2][1])});//最后一个区间是根据右边界是否在前面重叠区间中来考虑的。
        return result;
    }
};

时间复杂度: O(nlogn)

空间复杂度: O(logn),排序需要的空间开销

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

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

相关文章

构建强健身体的未来:健身管理平台微服务架构解析

在现代社会&#xff0c;人们越来越关注健康和身体素质的提升。健身管理平台应运而生&#xff0c;为用户提供个性化的健身计划、监测和管理工具。微服务架构作为一种灵活且可扩展的系统设计方法&#xff0c;为健身管理平台提供了高效、可靠的基础。 1. 概述健身管理平台微服务架…

Open CASCADE学习|统计形状拓扑数量

边界表示法&#xff08;Boundary Representation&#xff0c;简称B-Rep&#xff09;是几何造型中最成熟、无二义的表示法。它主要用于描述物体的几何信息和拓扑信息。在边界表示法中&#xff0c;一个实体&#xff08;Solid&#xff09;由一组封闭的面&#xff08;Face&#xff…

创建大量栅格文件并分别写入像元数据:C++ GDAL代码实现

本文介绍基于C语言GDAL库&#xff0c;批量创建大量栅格遥感影像文件&#xff0c;并将数据批量写入其中的方法。 首先&#xff0c;我们来明确一下本文所需实现的需求。已知我们对大量遥感影像进行了批量读取与数据处理操作——具体过程可以参考文章C GDAL提取多时相遥感影像中像…

nginx工作原理解析

目录 1、master-workers 的工作机制介绍 2、master-workers 的机制的好处 3、设置多少个 worker 4、最大连接数和支持的最大并发数的计算 1、master-workers 的工作机制介绍 nginx在启动后&#xff0c;会有一个master进程和一个或者多个相互独立的worker进程 过来的请求由…

HDLbits 刷题 --Exams/m2014 q4h

Implement the following circuit: 实现以下电路&#xff1a; module top_module (input in,output out);assign out in; endmodule 运行结果&#xff1a;

Spark_SparkSql写入Oracle_Undefined function.....将长字符串写入Oracle中方法..

在使用Spark编写代码将读库处理然后写入Oracle中遇到了诸多小bug,很磨人。shit!! 实测1&#xff1a;TO_CLOB(a3) 代码样例 --这是一个sparksql写入hive的一个小逻辑&#xff0c;我脱敏了噻 SELECT a1, a2, TO_CLOB(a3) AS clob_data, TO_DATE(a4) AS time FROM table1 WHERE…

关于Linux下的进程等待(进程篇)

目录 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 怎样去执行进程等待&#xff1f; status options 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 代码示例&#xff1a;模仿僵尸进程 #include <stdio.h> #include <unistd.…

3D-Aware Multi-Class Image-to-Image Translation with NeRFs

3D-Aware Multi-Class Image-to-Image Translation with NeRFs 利用NeRFs实现3D感知的多类图像到图像的翻译 Senmao Li1  Joost van de Weijer2  Yaxing Wang1 李森茂 1 范德维杰 2 王亚兴 1  Fahad Shahbaz Khan3,4  Meiqin Liu5  Jian Yang1 法哈德夏巴兹汗 3,4 刘梅琴 …

DSP笔记13-时间基准子模块Time base(TB)比较子模块Counter cpmpare(CC)

时间基准子模块Time base(TB) 同步&#xff0c;计数 CTR计数寄存器 PRD周期寄存器 CMP比较寄存器&#xff0c;占空比 EPWMA&#xff0c; EPWMB&#xff0c;两个比较寄存器&#xff0c;但只有以及计数寄存器以及一个周期寄存器 计数模式 计数时钟TBCLK HSPCLKDIVx x0,分…

存算架构优化:为大模型算力提升铺平道路

随着人工智能技术的飞速发展&#xff0c;大模型已经成为了推动各行各业进步的关键力量。从自然语言处理到图像识别&#xff0c;再到复杂的数据分析&#xff0c;大模型以其卓越的性能和广泛的应用前景&#xff0c;正逐渐成为AI领域的焦点。然而&#xff0c;大模型的高效运行离不…

Day 2. 2440相关知识点

1、arm的工作模式有哪些&#xff1f; ARM的工作模式分为普通模式、特权模式&#xff0c;其中特权模式又细分为六种模式 普通模式用户模式&#xff08;User&#xff09;大部分任务执行在这种模式 特权模式快速中断模式FIQ当一个高优先级&#xff08;fast) 中断产生时将会进入…

传输层协议——UDP/TCP协议

目录 端口号 端口号范围 pidof UDP协议 UDP协议格式 UDP特点 UDP缓冲区 UDP的注意事项 基于UDP的应用层协议 TCP协议 TCP协议格式 序号与确认序号 窗口大小 6个标记位 紧急指针 确认应答机制 连接管理机制 三次握手 四次挥手 超时重传机制 流量控制 滑动…

虚拟网络设备的真正使命:实现有控制的通信

在数字化时代&#x1f4f2;&#xff0c;网络安全&#x1f512;成为了企业和个人防御体系中不可或缺的一部分。随着网络攻击的日益复杂和频繁&#x1f525;&#xff0c;传统的物理网络安全措施已经无法满足快速发展的需求。虚拟网络设备&#x1f5a7;&#xff0c;作为网络架构中…

快速删除node_modules

1.rd /s /q node_modules 2.rimraf node_modules/ 亲测可用

「JavaEE」初识进程

初识进程 &#x1f349;进程&#x1f34c;操作系统的进程管理 &#x1f349;PCB 重要属性&#x1f34c;进程的身份标识&#x1f34c;内存指针&#x1f34c;文件描述符表&#x1f34c;进程的状态&#x1f34c;优先级&#x1f34c;记账信息&#x1f34c;上下文 &#x1f349;内存…

网络安全---RSA公钥加密与签名

实验项目&#xff1a;RSA公钥加密与签名实验 1.实验目的 本实验的学习目标是让学生获得 RSA 算法的动手经验。 通过课堂学习&#xff0c;学生应该已经了解 RSA 算法的理论部分&#xff0c; 知道在数学上如何生成公钥、私钥以及如何执行加密、解密和签名生成、验证。 通过使用…

前端保留两位小数

一、保留两位小数&#xff08;四舍五入&#xff09; 解决方案&#xff1a;使用 toFixed(x) 方法可以对小数进行指定位数保留&#xff0c;其中x是要保留的位数用法&#xff1a;num.toFixed(x)&#xff0c;其中num为需要操作的数据&#xff0c;x为要保留的位数示例&#xff1a;1…

【leetcode】动态规划::前缀和(二)

标题&#xff1a;【leetcode】前缀和&#xff08;二&#xff09; 水墨不写bug 正文开始&#xff1a; &#xff08;一&#xff09; 和为K的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续…

Redis从入门到精通(十一)Redis实战(八)关注、共同关注和Feed流

↑↑↑请在文章开头处下载测试项目源代码↑↑↑ 文章目录 前言4.9 好友关注4.9.1 关注和取消关注4.9.1.1 创建表是实体类4.9.1.2 实现关注和取消关注 4.9.2 共同关注4.9.2.1 改造关注和取消关注功能4.9.2.2 实现查询共同关注好友功能 4.9.3 Feed流4.9.3.1 Feed流介绍及其实现模…

蓝桥杯模拟赛题——魔法失灵了——toRefs()

目标 找到 index.html 中 TODO 部分&#xff0c;正确修复代码使 data 对象恢复响应式特性&#xff0c;即点击页面上的 - 与 按钮可以改变 value 的值。正确实现后效果如下&#xff1a; 题解 value是reactive 利用toRefs; toRefs() 函数可以将 reactive() 创建出来的响应式对象…