zoukankan      html  css  js  c++  java
  • [刷题] 435 Non-overlapping Intervals

    要求

    • 贪心算法与动态规划的关系
    • 给定一组区间,最少删除多少个区间,可以让这些区间之间互相不重叠
    • 给定区间的起始点永远小于终止点

    示例

    • [[1,2],[2,3],[3,4],[1,3]], 返回1
    • [[1,2],[1,2],[1,2]], 返回2

    思路

    • 等价为最多保留多少个区间
    • 暴力:找出所有子区间的组合,判断不重叠((2^n)*n)
    • 先排序,方便判断不重叠
    • 具体实现类似最长上升子序列
    • 选择区间的结尾很重要,结尾越小,留给后面的空间越大

    实现

    • 动态规划(n^2)
    • dp[i]:使用intervals[0...i]的区间所能构成的最长不重叠区间序列
     1 class Solution {
     2 public:
     3     int eraseOverlapIntervals(vector<vector<int>>& intervals) {
     4 
     5         if(intervals.size() == 0)
     6             return 0;
     7 
     8         sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){
     9             if(a[0] != b[0]) return a[0] < b[0];
    10             return a[1] < b[1];
    11         });
    12 
    13         vector<int> dp(intervals.size(), 1);
    14         for(int i = 1 ; i < intervals.size() ; i ++)
    15             for(int j = 0 ; j < i ; j ++)
    16                 if(intervals[i][0] >= intervals[j][1])
    17                     dp[i] = max(dp[i], 1 + dp[j]);
    18 
    19         return intervals.size() - dp.back();
    20     }
    21 };
    View Code
    • 贪心算法(n)
    • 按照区间结尾排序,每次选择结尾最早的,且和前一个区间不重叠的区间
    • 贪心选择性质:贪心算法为A,最优算法为O,A完全能替代O,且不影响求出最优解
    • 若无法使用贪心算法,举出反例即可
    • 证明正确性,可使用数学归纳法
      • 某次选择的是[s(i),f(i)],其中f(i)是当前所有选择中结尾最早的
      • 假设这个选择不是最优的,若最优解为k,则这个选择得到的解,最多为k-1
      • 假设最优解在这一步选择[s(j),f(j)],其中f(j)>f(i)
      • 显然可用[s(i),f(i)]替换[s(j),f(j)],而不影响后续的区间选择
      • 即当选择[s(i),f(i)]时,也构成了大小为k的解,矛盾
      • 此问题具有贪心选择性,可以用贪心算法得到最优解
     1 class Solution {
     2 
     3 public:
     4     int eraseOverlapIntervals(vector<vector<int>>& intervals){
     5 
     6         if(intervals.size() == 0)
     7             return 0;
     8 
     9         sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){
    10             if(a[0] != b[0]) return a[0] < b[0];
    11             return a[1] < b[1];
    12         });
    13 
    14         int res = 1;
    15         int pre = 0;
    16         for(int i = 1 ; i < intervals.size() ; i ++)
    17             if(intervals[i][0] >= intervals[pre][1]){
    18                 pre = i;
    19                 res ++;
    20             }
    21             else if(intervals[i][1] < intervals[pre][1])
    22                 pre = i;
    23 
    24         return intervals.size() - res;
    25     }
    26 };
    View Code

    应用

    • 最小生成树
    • 最短路径
  • 相关阅读:
    RxJava学习经验谈——map与flatmap
    不要打断链式结构:使用 RxJava的 compose() 操作符
    Android Retrofit网络请求Service,@Path、@Query、@QueryMap、@Map...
    Android 勤用RXJava compose操作符消除重复代码
    Android使用token维持登陆状态的方法
    Java服务器对外提供接口以及Android端向服务器请求数据
    Retrofit请求数据对错误以及网络异常的处理
    Retrofit2.0+OkHttp打印Request URL(请求地址参数)
    HUE配置文件hue.ini 的hbase模块详解(图文详解)(分HA集群和非HA集群)
    安装Hue后的一些功能的问题解决干货总结(博主推荐)
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12776773.html
Copyright © 2011-2022 走看看