【Day26 LeetCode】贪心Ⅳ

一、贪心

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

对右区间进行排序,然后判断其它区间是否与该区间有重叠。

class Solution {
    static bool cmp(vector &a, vector &b){
        return a[1] < b[1];
    }
public:
    int findMinArrowShots(vector>& points) {
        // 对右区间进行排序
        sort(points.begin(), points.end(), cmp);
        int pre = points[0][1], ans = 1;
        for(auto point : points){
            if(point[0] > pre){
                ++ans;
                pre = point[1];
            }
        }
        return ans;
    }
};

2、无重叠区间 435

思路:先对右区间进行排序,比较当前区间与前一个可比较区间是否重叠。为什么要对右区间排序?能保证这个区间整体都偏小,而如果按左区间排序,由于区间长度未知,可能区间的范围很大。

class Solution {
    static bool cmp(const vector& a, const vector& b) {
        if (a[1] == b[1]) return a[0] < b[0];
        return a[1] < b[1];
    }
public:
    int eraseOverlapIntervals(vector>& intervals) {
        sort(intervals.begin(), intervals.end(), cmp);
        int ans = 0, pre = intervals[0][1];
        for(int i=1; i= pre)
                pre = intervals[i][1];
            else
                ++ans;
        }
        return ans;
    }
};

后面转念一想,对左区间排序可不可行呢?也可行,不过发生重叠时需要取右区间较小的范围,这样也能保持整体取较小的值。

class Solution {
public:
    int eraseOverlapIntervals(vector>& intervals) {
        sort(intervals.begin(), intervals.end());
        int ans = 0, pre = intervals[0][1];
        for(int i=1; i= pre){
                pre = intervals[i][1];
            }else{
                pre = min(pre, intervals[i][1]);
                ++ans;
            }
        }
        return ans;
    }
};

3、划分字母区间 763

找到起点字符最后出现的位置,不断更新这个范围内的字符所能达到最远位置,直到到达最远位置,就是一个划分。

class Solution {
public:
    vector partitionLabels(string s) {
        unordered_map mp;
        // 记录每个字符最后出现的位置
        for(int i=0; i ans;
        int start = 0, end = 0;
        for(int i=0; i

二、写在后面

今天主要涉及区间的合并、划分等,排序是区间问题的常见操作,至于是对区间的左区间还是右区间排序需要斟酌

你可能感兴趣的:(leetcode,算法)