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

C++ day36 贪心算法 无重叠区间 划分字母区间 合并区间

题目1:435 无重叠区间

题目链接:无重叠区间

对题目的理解

移除数组中的元素,使得区间互不重叠,保证移除的元素数量最少,数组中至少包含一个元素

贪心算法

局部最优,使得重叠区间的个数最大,全局最优,移除最少的元素

本题和昨天引爆气球的题目相似,还是对数组进行排序(按照左边界排序和右边界排序均可),这里还是选择的左边界排序

代码的精华所在

伪代码

完整代码

class Solution {
public:
    static bool cmp(const vector<int>& a, vector<int>& b){
        return a[0]<b[0];//将左边界从小到大排序
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size()==0) return 0;
        //首先对数组的起始坐标进行从小到大排序
        sort(intervals.begin(),intervals.end(),cmp);
        int count=0;
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]<intervals[i-1][1]){
                count++;
                //更新当前重叠区间的最小右边界
                intervals[i][1] = min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return count;

    }
};
  • 时间复杂度:O(nlog n) ,有一个快排
  • 空间复杂度:O(n),有一个快排,最差情况(倒序)时,需要n次递归调用。因此确实需要O(n)的栈空间

题目2:763 划分字母区间

题目链接:划分字母区间

对题目的理解

由小写字母构成的字符串划分为尽可能多的片段,每个字母最多再一个片段中出现,比如,字母a在第一个片段中出现了,那么a就不能在之后的片段中出现了,注意划分的结果顺序拼接仍为原字符串,最终返回每个片段的长度

一旦包含了某个字母,就不得不向后遍历,使得该字母只出现在这个区间里,寻找所有的该字母,最终将该片段分割,就是寻找该区间里所有字母的最远边界,这个边界就是分割点。

可以分为如下两步:

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

伪代码

完整代码

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27]= {0};
        for(int i=0;i<s.size();i++){
            hash[s[i]-'a'] = i;//求解字符串中每个字母出现的最远下标
        }
        int left=0,right = 0;//定义片段的左下标,右下标,计算片段的长度
        vector<int> result;
        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;

    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1),使用的hash数组是固定大小

题目3:56 合并区间

题目链接:合并区间

对题目的理解

合并数组中的重叠区间,返回一个不重叠的区间数组,这个数组覆盖输入的所有区间

注意[1,4]和[4,5]也可以合并,合并成[1,5]

本题的本质其实还是判断重叠区间问题

还是先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,我还是按照左边界进行排序,然后考虑重叠的区间,更新右边界的最大值,对于不重叠的区间,直接存放到result数组中

伪代码

代码

class Solution {
public:
    static bool cmp(const vector<int>& a, vector<int>& b){
        return a[0]<b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if(intervals.size()==0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        vector<vector<int>> result ;
        result.push_back(intervals[0]);
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]<=result.back()[1]){//重叠
                //左边界不用更新,因为左边界是按照从小到大排的
                //只更新右边界
                result.back()[1] = max(intervals[i][1],result.back()[1]);
                }
            else{//没有重叠
                result.push_back(intervals[i]);
            }
        }
        return result;
    }
};
  • 时间复杂度: O(nlogn)
  • 空间复杂度: O(logn),排序需要的空间开销

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

相关文章:

  • 设计模式-七个基本原则之一-迪米特法则 + 案例
  • 【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-最大的数
  • 券商隔夜单自动下单交易接口
  • 人工智能的前沿研究方向与未来发展趋势
  • mysql 更改 字段长度
  • 期权懂|期权新手入门教学:期权合约有哪些要素?
  • 计算机网络高频面试八股文
  • 解决Hadoop DataNode ‘Incompatible clusterIDs‘报错
  • 关于Unity中字典在Inspector的显示
  • 一、Lua基础
  • 【C++ 程序设计入门基础】- 第3节-循环结构01
  • Linux配置路由功能及添加静态路由
  • 免费查找文献期刊数据论文网站
  • 【Qt之QTextDocument】使用及表格显示富文本解决方案
  • 基于STC12C5A60S2系列1T 8051单片机的IIC总线器件24C02记录单片机上电次数应用
  • kubectl rollout 实现金丝雀发布的流量控制策略
  • 经典滑动窗口试题(二)
  • 【LeetCode刷题-链表】--86.分隔链表
  • LLM、ChatGPT与多模态必读论文150篇
  • 使用opencv将sRGB格式的图片转换为Adobe-RGB格式【sRGB】【Adobe-RGB】
  • 数据挖掘 朴素贝叶斯
  • tp6框架 万级数据入库 php函数优化
  • 如何解决 Java 中的 IllegalArgumentException 异常?
  • Windows10系统卸载服务和删除服务
  • 使用STM32 HAL库驱动光电传感器的设计和优化
  • Python算法——Merkle树