[Leetcode]435. 无重叠区间

435. 无重叠区间

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。

示例 1:

输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

想到了经典的会议安排问题,常规两种解法,一种动态规划,一种贪心,动态规划过不了全部数据会超时

动态规划

官方解释:

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int i, j, n = intervals.size();

        // 初始化为 1 是为了在状态转移时,如果前 i - 1 个不存在满足条件的 则默认为1(本身)
        vector<int> f(n,1);

        // 按照左端点升序进行排序
        sort(intervals.begin(), intervals.end(), [](const vector<int> &a, const vector<int> &b){ // 满足条件进入
            return a[0] < b[0];
        });

        for (i = 1; i < n; i++) {
            for(j = 0; j < i; j++){

                if(intervals[j][1] <= intervals[i][0]){
                    f[i] = max(f[i], f[j] + 1);
                }
            }
        }
        n = n - *max_element(f.begin(), f.end());
        return n;
    }   
};

贪心

放一个会议安排问题直观说明(来源:Ruby爸爸)

// 贪心算法
class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int result = 1, n = intervals.size();
        int i, j, right;
        // 这里注意 需要 & 直接传地址,否则拷贝耗时导致超时
        sort(intervals.begin(), intervals.end(), [](const vector<int> &a, const vector<int> &b){
            return a[1] < b[1];
        });

        right = intervals[0][1];
        for(i = 1; i < n; i++){
            if( intervals[i][0] >= right){
                result++;
                right = intervals[i][1];
            }
        }
        return n - result;
    }
};

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/non-overlapping-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted @ 2023-02-15 19:27  LLeaves  阅读(27)  评论(0编辑  收藏  举报