作者 | labuladong

来源 | labuladong(ID:labuladong)

【导读】什么是贪心算法呢?贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高。

比如说一个算法问题使用暴力解法需要指数级时间,如果能使用动态规划消除重叠子问题,就可以降到多项式级别的时间,如果满足贪心选择性质,那么可以进一步降低时间复杂度,达到线性级别的。

什么是贪心选择性质呢,简单说就是:每一步都做出一个局部最优的选择,最终的结果就是全局最优。注意哦,这是一种特殊性质,其实只有一小部分问题拥有这个性质。

比如你面前放着 100 张人民币,你只能拿十张,怎么才能拿最多的面额?显然每次选择剩下钞票中面值最大的一张,最后你的选择一定是最优的。

然而,大部分问题都明显不具有贪心选择性质。比如打斗地主,对手出对儿三,按照贪心策略,你应该出尽可能小的牌刚好压制住对方,但现实情况我们甚至可能会出王炸。这种情况就不能用贪心算法,而得使用动态规划解决,参见前文 动态规划解决博弈问题。

一、问题概述

言归正传,本文解决一个很经典的贪心算法问题 Interval Scheduling(区间调度问题)。给你很多形如[start,end]的闭区间,请你设计一个算法,算出这些区间中最多有几个互不相交的区间。

举个例子,intvs=[[1,3],[2,4],[3,6]],这些区间最多有两个区间互不相交,即[[1,3],[3,6]],你的算法应该返回 2。注意边界相同并不算相交。

这个问题在生活中的应用广泛,比如你今天有好几个活动,每个活动都可以用区间[start,end]表示开始和结束的时间,请问你今天最多能参加几个活动呢?

二、贪心解法

这个问题有许多看起来不错的解决思路,实际上都不能得到正确答案。比如说:

也许我们可以每次选择可选区间中开始最早的那个?但是可能存在某些区间开始很早,但是很长,使得我们错误地错过了一些短的区间。

或者我们每次选择可选区间中最短的那个?或者选择出现冲突最少的那个区间?这些方案都能很容易举出反例,不是正确的方案。

正确的思路其实很简单,可以分为以下三步:

  1. 从区间集合 intvs 中选择一个区间 x,这个 x 是在当前所有区间中结束最早的(end 最小)。

  2. 把所有与 x 区间相交的区间从区间集合 intvs 中删除。

  3. 重复步骤 1 和 2,直到 intvs 为空为止。之前选出的那些 x 就是最大不相交子集。

把这个思路实现成算法的话,可以按每个区间的end数值升序排序,因为这样处理之后实现步骤 1 和步骤 2 都方便很多:

现在来实现算法,对于步骤 1,由于我们预先按照end排了序,所以选择 x 是很容易的。关键在于,如何去除与 x 相交的区间,选择下一轮循环的 x 呢?

由于我们事先排了序,不难发现所有与 x 相交的区间必然会与 x 的end相交;如果一个区间不想与 x 的end相交,它的start必须要大于(或等于)x 的end:

下面看下代码:

三、应用举例

下面举例几道 LeetCode 题目应用一下区间调度算法。

第 435 题,无重叠区间:

我们已经会求最多有几个区间不会重叠了,那么剩下的不就是至少需要去除的区间吗?

int eraseOverlapIntervals(int[][] intervals) { int n = intervals.length;  return n - intervalSchedule(intervals);
}

第 452 题,用最少的箭头射爆气球:

其实稍微思考一下,这个问题和区间调度算法一模一样!如果最多有n个不重叠的区间,那么就至少需要n个箭头穿透所有区间:

只是有一点不一样,在intervalSchedule算法中,如果两个区间的边界触碰,不算重叠;而按照这道题目的描述,箭头如果碰到气球的边界气球也会爆炸,所以说相当于区间的边界触碰也算重叠:

所以只要将之前的算法稍作修改,就是这道题目的答案:

int findMinArrowShots(int[][] intvs) {    // ...  for (int[] interval : intvs) {  int start = interval[0];   // 把 >= 改成 > 就行了 if (start > x_end) { count++;  x_end = interval[1];   }   }   return count;
}

这么做的原因也不难理解,因为现在边界接触也算重叠,所以start == x_end时不能更新区间 x。

本文终。对于区间问题的处理,一般来说第一步都是排序,相当于预处理降低后续操作难度。但是对于不同的问题,排序的方式可能不同,这个需要归纳总结,以后再写写这方面的文章。

(*本文为 AI科技大本营转载文章,转载请联系作者)

福利时刻

入群参与每周抽奖~

扫码添加小助手,回复:大会,加入福利群,参与抽奖送礼!

大会5折优惠票倒计时 1 天! 团购还享立减优惠,倒计时 1 天!此外,伯克利大学名师精髓课程移师北京。《动手学深度学习》作者、亚马逊首席科学家李沐线下亲授「深度学习实训营」,免费GPU资源,现场还将限量赠送价值85元的配套书籍一本,先到先得。原价1099元,限时专享CSDN 独家福利价199元识别海报二维码,即刻购票~

推荐阅读

  • 2019 AI ProCon日程出炉:Amazon首席科学家李沐亲授「深度学习」

  • 玩嗨的2亿快手“老铁”和幕后的极致视觉算法

  • 与旷视、商汤等上百家企业同台竞技?AI Top 30+案例评选等你来秀

  • 从不温不火到炙手可热:语音识别技术简史

  • 入门大爆炸式发展的深度学习,你先要了解这6个著名框架

  • 用Python的算法工程师们,编码问题搞透彻了吗?

  • Python冷知识,不一样的技巧带给你不一样的乐趣

  • 我是如何通过开源项目月入 10 万的?

  • 撬动百亿台设备,让物联网“造”起来!

  • 程序员离无人值班有多远?

你点的每个“在看”,我都认真当成了喜欢

一份贪心算法区间调度问题解法攻略,拿走不谢相关推荐

  1. java贪心算法 区间调度_贪心算法-区间调度问题解之证明(示例代码)

    一.贪心算法 定义:一个算法是贪心算法,如果它是通过一些小的步骤来一个求解,并且在每一步根据局部情况选择一个决定,使得某些主要的指标得到优化. 二.区间调度问题 1. 问题:我们有一组需求{1,2,3 ...

  2. 贪心算法区间调度问题思路代码证明

    1.活动安排问题 问题:有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 解题思路:将活动按照结束时间进行从小到大排序,挑选出结束时间尽量 ...

  3. 贪心算法—区间调度 电影节(POJ 4151)

    贪心算法--区间选取问题 或是区间调度问题 本文解决一个很经典的贪心算法问题 Interval Scheduling(区间调度问题).给你很多形如[start,end]的闭区间,请你设计一个算法,算出 ...

  4. matlab车辆贪心作业调度,贪心算法-区间调度-Interval Scheduling

    什么是贪心算法呢? 贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高. 比如说一个算法问题使用暴力解法需要指数级时间,如果 ...

  5. 贪心算法——区间选点问题

    转载:https://blog.csdn.net/xia842655187/article/details/51944763 区间选点的问题大致可以描述为:  给定N个区间[a,b],取尽量少的点,使 ...

  6. 贪心算法思想详解+示例代码

    CSDN话题挑战赛第2期 参赛话题:学习笔记 文章目录 五大算法思想 贪心算法 举例说明 选择排序 删除数字 寻找数字最大和 买股票 最大回文字符串 背包问题 小结 五大算法思想 分治思想 贪心算法/ ...

  7. 【算法图解】 之 [贪婪算法(贪心算法)] 详解

    入门算法学习,看的第一本是深入浅出的<算法图解>一书,本博客是对<算法图解>一书的学习笔记,将书中的分享的算法示例用Python3语言实现. 如果你也想要阅读这本书,百度云盘链 ...

  8. 跳格子/贪心算法例题详解:LeetCode605.种花问题

    今天做了一道很有意思的题目,虽然是分属于贪心算法的一个题目,但是解法多样,十分有趣,且不是很难理解,所以想在这里分享给大家. 题目描述: 假设有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是 ...

  9. 嵌入式必会!C语言最常用的贪心算法就这么被攻略了

    01 基本概念 贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的 ...

最新文章

  1. java实现简易客户信息管理系统
  2. Oracle单行函数
  3. 用GNS3做PIX防火墙ICMP实验
  4. Linux 运维入门到跑路书单推荐
  5. bzoj4709 [Jsoi2011]柠檬
  6. 工业控制系统ICS网络安全简析
  7. 人为漏洞的构造、文件的载入、验证机制的突破
  8. linux VNC白屏,VNC使用及其常见问题解决方法
  9. ie 代理设置中地址和端口置灰的解决办法
  10. 2019校招Android面试题解1.0
  11. Angularjs的IOC Inject分析
  12. java题库软件_基于JAVA题库管理系统.doc
  13. JAVA网络编程实战(笔记)
  14. 红外解码软件 android,红外线遥控器软件解码程序(能解大部分遥控器的编码)
  15. [UE4]打包运行时提示Plugin ‘‘ failed to load because module ‘‘ could not be found.缺少插件解决方法
  16. tf15: 中文语音识别
  17. 百度何中军:机器翻译——从设想到大规模应用
  18. 【20210122期AI简报】保姆级深度学习环境配置指南、寒武纪首颗AI训练芯片亮相...
  19. MyEclipse7.02注册码
  20. 软件需求——需求规格说明书模版(三)

热门文章

  1. Spring MVC配置
  2. 按键驱动的恩恩怨怨之概述
  3. Android系统移植与调试之-------如何修改Android设备添加重启、飞行模式、静音模式等功能(一)...
  4. 正则表达式实现最小匹配
  5. 常用C/C++开源库
  6. oracle 判断11位数字,45个非常有用的 Oracle 查询语句小结
  7. python插入排序演示源码
  8. oracle终止用户会话
  9. xx.xib: error: Illegal Configuration: Safe Area Layout Guide before iOS 9.0报错问题解决
  10. 前端相关html和css