贪心算法专题Day21:区间问题

452. 用最少数量的箭引爆气球

1.按气球的左侧排序

2.维护一个start,end区间,若下一个气球在之前气球范围外就需要多加一个飞镖,反之,不需要,end维护为两者重叠部分,即更小的end。

cpp 复制代码
    static bool cmp(const vector<int>a, const vector<int>b){
        if(a[0] == b[0]){
            return a[1] < b[1];
        }
        return a[0]<b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(), points.end());
        int start = points[0][0];
        int end = points[0][1];
        int count = 1;
        for(int i = 1; i < points.size(); i++){
            if(points[i][0] <= end){
                end = min(points[i][1], end);
            }
            else{
                start = points[i][0];
                end = points[i][1];
                count++;
            }
        }
        return count;
    }

435. 无重叠区间

排序:先按区间左端点升序(左端点相同则按右端点升序),让区间按 "从左到右" 的顺序排列;

遍历判断 :维护当前不重叠区间的「最右端点」end,遍历后续区间:

  • 若当前区间和end重叠 → 需要删除(计数 + 1),且更新end为「更小的右端点」(保留更短的区间,减少后续重叠);

  • 若不重叠 → 更新end为当前区间的右端点(当前区间成为新的 "不重叠基准");

cpp 复制代码
    static bool cmp(const vector<int>a, const vector<int>b) {
        if(a[0] == b[0]){
            return a[1] < b[1];
        }
        return a[0] < b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        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){
                count++;
                end = min(intervals[i][1], end);//选择跨度尽可能小的
            }
            else {
                end = intervals[i][1];
            }
        }
        return count;
    }

763. 划分字母区间

预处理(记录最后位置) :遍历字符串,记录每个字符在字符串中最后一次出现的下标 (比如字符 'a' 最后出现在下标 8,就记pos['a'-'a']=8);

贪心划分区间 :遍历字符串,维护当前区间的「起始位置start」和「最远边界end」:

  • 遍历过程中,不断扩展end为 "当前字符最后出现位置" 和 "当前end" 的最大值(保证区间内所有字符的最后位置都在区间内);

  • 当遍历到end时,说明当前区间的所有字符都不会超出这个边界 → 完成一次划分,记录长度,重置startend

  • 遍历结束后,处理最后一个区间。

cpp 复制代码
    vector<int> partitionLabels(string s) {
        int pos[26] = {0};
        for(int i = 0; i < s.length(); i++){
            pos[s[i] - 'a'] = i;
        }
        vector<int> res;
        int start = 0;
        int end = pos[s[0] - 'a'];
        int len = 0;
        for(int i = 0; i < s.length(); i++){
            if(i <= end){
                end = max(pos[s[i] - 'a'], end);
            }
            else{
                len = end - start + 1;
                res.push_back(len);
                start = i;
                end = pos[s[i] - 'a'];
            }
        }
        len = end - start + 1;
        res.push_back(len);
        return res;
    }
相关推荐
鱼很腾apoc8 小时前
【学习篇】第20期 超详解 C++ 多态:从语法规则到底层原理
java·c语言·开发语言·c++·学习·算法·青少年编程
小许同学记录成长9 小时前
三维重建技术文档
算法·无人机
小O的算法实验室11 小时前
2026年ASOC,基于多目标优化去噪双存档进化算法+路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
2601_9545267511 小时前
逆向解析Temu底层动销算法:基于API高并发轮询与全域存量透视的自动化架构重构
算法·架构·自动化
Σίσυφος190012 小时前
数据标准化(拟合的时候使用非常重要)
人工智能·算法
knight_9___12 小时前
大模型project面试7
人工智能·python·算法·面试·大模型·agent
NashSKY13 小时前
EM 算法完整推导与本质剖析
算法·机器学习·概率论
foundbug99913 小时前
MATLAB实现:基于图像对比度和波段相关性的高光谱波段选择算法
开发语言·算法·matlab
嘿嘿嘿x313 小时前
Linux-实践
linux·运维·算法