区间覆盖问题

本文探讨了区间覆盖问题,通过贪心和动态规划两种方法寻找覆盖最少小区间的解。贪心策略是每次选择右端点最大的可达区间;动态规划则通过左端点排序和转移公式来解决。文章还提到了该思路在LeetCode上几道题目的应用,如55.跳跃游戏、45. 跳跃游戏 II等。
摘要由CSDN通过智能技术生成

区间覆盖问题,一般可以抽象为给定一些小区间,从中选择一些区间,能够覆盖,求最少选择多少个小区间的问题。

一般有两种做法: 贪心、动态规划。

贪心

贪心法基于这样的考虑:

因为x=s这个点是必须要被覆盖的,在可以覆盖到s的小区间里,选择右端点最大的小区间,是最优解。之后每一次,在左端点可达的小区间里,都选择右端点最大的区间,这样迭代下来,选出的小区间是最优解。

注意每次都要选择左端点可达的小区间,这个条件是完成覆盖的前提。

因此,首先排除掉所有的小区间,这些小区间肯定不是可达的。之后将所有小区间按照左端点进行排序,第一步左端点可达的小区间是所有包含x=s的区间。之后每次迭代都按照相同的策略进行。

简化起见,假设排序后第一个小区间能够覆盖s。

那么可以写出伪代码如下:

public int solve(int[][] intervals, int s, int e){
    //按左端点排序
    Arrays.sort(intervals, Comparators.compareInt(o -> o[0]);
    //l:能覆盖的左端点,每次迭代中满足 si <= l 的小区间被认为是可达的。
    //r:能覆盖的右端点。
    //idx: 遍历intervals数组的下标。
    int l = 0, r = 0, idx = 0, n = intervals.length;
    while(r < e && idx < n){
        //遍历所有可达的小区间,找到能向右覆盖的最大范围
        while(idx < n && intervals[idx][0] <= l){
            r = Math.max(r, intervals[idx][1];
        }
        //无法再向右覆盖,无解
        if(l == r){
            return -1;
        }
        //这一轮迭代结束
        l = r;
        ans++;
    }
    return r >= e ? ans : -1; 
}

动态规划

动态规划的转移推导如下:

首先同样按照左端点将所有小区间排序。

假设是能够覆盖的最少区间数量,此时新增一个小区间,能够覆盖,也就是满足,那么可以得到转移公式

初始,其余点都设置为INF表示不可达。之后只需要遍历每一个小区间,从左向右更新

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值