本文 https://github.com/youngyangyang04/leetcode-master 已经收录,里面还有leetcode刷题攻略、各个类型经典题目刷题顺序、思维导图,可以fork到自己仓库,有空看一看一定会有所收获,如果对你有帮助也给一个star支持一下吧!

56. 合并区间

题目链接:https://leetcode-cn.com/problems/merge-intervals/

给出一个区间的集合,请合并所有重叠的区间。

示例 1:
输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:
输入: intervals = [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。

提示:

  • intervals[i][0] <= intervals[i][1]

思路

大家应该都感觉到了,此题一定要排序,那么按照左边界排序,还是右边界排序呢?

都可以!

那么我按照左边界排序,排序之后局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间了,整体最优:合并所有重叠的区间。

局部最优可以推出全局最优,找不出反例,试试贪心。

那有同学问了,本来不就应该合并最大右边界么,这和贪心有啥关系?

有时候贪心就是常识!哈哈

按照左边界从小到大排序之后,如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]左边界 < intervals[i - 1]右边界,则一定有重复,因为intervals[i]的左边界一定是大于等于intervals[i - 1]的左边界。

即:intervals[i]的左边界在intervals[i - 1]左边界和右边界的范围内,那么一定有重复!

这么说有点抽象,看图:(注意图中区间都是按照左边界排序之后了

知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

C++代码如下:

class Solution {
public:// 按照区间左边界从小到大排序static bool cmp (const vector<int>& a, const vector<int>& b) {return a[0] < b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> result;if (intervals.size() == 0) return result;sort(intervals.begin(), intervals.end(), cmp);bool flag = false; // 标记最后一个区间有没有合并int length = intervals.size();for (int i = 1; i < length; i++) {int start = intervals[i - 1][0];    // 初始为i-1区间的左边界int end = intervals[i - 1][1];      // 初始i-1区间的右边界while (i < length && intervals[i][0] <= end) { // 合并区间end = max(end, intervals[i][1]);    // 不断更新右区间if (i == length - 1) flag = true;   // 最后一个区间也合并了i++;                                // 继续合并下一个区间}// start和end是表示intervals[i - 1]的左边界右边界,所以最优intervals[i]区间是否合并了要标记一下result.push_back({start, end}); }// 如果最后一个区间没有合并,将其加入resultif (flag == false) {result.push_back({intervals[length - 1][0], intervals[length - 1][1]});}return result;}
};

当然以上代码有冗余一些,可以优化一下,如下:(思路是一样的)

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> result;if (intervals.size() == 0) return result;// 排序的参数使用了lamda表达式sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){return a[0] < b[0];});result.push_back(intervals[0]);for (int i = 1; i < intervals.size(); i++) {if (result.back()[1] >= intervals[i][0]) { // 合并区间result.back()[1] = max(result.back()[1], intervals[i][1]);} else {result.push_back(intervals[i]);}}return result;}
};
  • 时间复杂度:O(nlogn) ,有一个快排
  • 空间复杂度:O(1),不算result数组(返回值所需容器占的空间)

总结

对于贪心算法,很多同学都是:如果能凭常识直接做出来,就会感觉不到自己用了贪心, 一旦第一直觉想不出来, 可能就一直想不出来了

跟着「代码随想录」刷题的录友应该感受过,贪心难起来,真的难。

那应该怎么办呢?

正如我贪心系列开篇词关于贪心算法,你该了解这些!中讲解的一样,贪心本来就没有套路,也没有框架,所以各种常规解法需要多接触多练习,自然而然才会想到。

「代码随想录」会把贪心常见的经典题目覆盖到,大家只要认真学习打卡就可以了。

我是程序员Carl,可以找我组队刷题,也可以在B站上找到我,本文leetcode刷题攻略已收录,更多精彩算法文章尽在公众号:代码随想录,关注后就会发现和「代码随想录」相见恨晚!

如果感觉对你有帮助,不要吝啬给一个

「leetcode」56. 合并区间【贪心算法】详细图解!相关推荐

  1. 164. Leetcode 435. 无重叠区间 (贪心算法-贪心区间)

    class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if len(interval ...

  2. java区间合并_贪心算法:合并区间

    ❝ 最近文章阅读量少了很多啊打卡也少了, 是不是年底了很多录友在忙期末考试啊,哈哈. 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: intervals = [[1,3],[2,6], ...

  3. 力扣记录:贪心算法3较难(1)区间问题——55 跳跃游戏,45 跳跃游戏II,452 用最少数量的箭引爆气球,435 无重叠区间,763 划分字母区间,56 合并区间

    本次题目 55 跳跃游戏 45 跳跃游戏II 452 用最少数量的箭引爆气球 435 无重叠区间 763 划分字母区间 56 合并区间 55 跳跃游戏 局部最优:不管每次跳多少步,取最大跳跃步数,若覆 ...

  4. leetcode 56. 合并区间

    leetcode 56. 合并区间 题目描述: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] .请你合并所有重叠的区间, ...

  5. LeetCode 56 合并区间

    56. 合并区间 难度中等1153收藏分享切换为英文接收动态反馈 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] .请你合 ...

  6. 56. 合并区间 排序数组

    https://www.b2bchain.cn/6393.html 56. 合并区间首先对开始元素进行排序 之后比较结尾元素判断是否可以加入合并集合//给出一个区间的集合,请合并所有重叠的区间. // ...

  7. 56. 合并区间 golang

    56. 合并区间 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: ...

  8. js实现kmp算法_「leetcode」459.重复的子字符串:KMP算法还能干这个!

    不瞒你说,重复子串问题,KMP很拿手 题目459.重复的子字符串 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: ...

  9. LeetCode 55跳跃游戏56合并区间57插入区间

    原创公众号:bigsai 希望和优秀的你做朋友,感觉不错还请一键三连. 回复进群即可加入和200+人一起打卡.上周打卡: LeetCode 47全排列Ⅱ&48旋转图像 LeetCode 49字 ...

  10. 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!

    构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...

最新文章

  1. 【问链财经-区块链基础知识系列】 第二十八课 区块链如何助力万亿规模的供应链金融蛋糕
  2. docker与kuberentes基本概念与操作学习
  3. 如何处理班级过多的问题
  4. 十、request.getSession( )、reqeust.getSession(false)和 request.getSession(true)
  5. linux挂载查看、添加与取消
  6. jQuery——入门(四)JQuery 事件
  7. vs2013使用remote debug
  8. -Dmaven.multiModuleProjectDirectory system propery is not set.
  9. debian编译openjdk8
  10. 人工智能机器学习算法
  11. php屏蔽中文浏览器,网站屏蔽中文浏览器/英文浏览器方法
  12. 数字时钟word clock Mac设置教程
  13. hue oozie rerun使用问题记录
  14. android矢量图之VectorDrawable ,自由又方便的填充色彩
  15. GitChat · 前端 | Webpack 工程的 PWA 实战
  16. 优化问题---梯度、方向导数、法线
  17. 明天就是七夕了,用Python做了个可能会被女朋友打死的礼物!
  18. Xcode - 使用 DWURecyclingAlert 进行 UITableView 和 UICollectionView 的绘图性能测试https://viktyz.gitbooks.io/ios
  19. 【Springboot系列】Springboot接管所有Controller,magic-api源码阅读
  20. 一:FPGA从入门倒入坟-第一个基础实例蜂鸣器

热门文章

  1. MySQL索引类型及优化
  2. swing简单的打字游戏源码
  3. MVC 异常处理机制
  4. C# 生成高清缩略图
  5. ak330s 置换内外sd
  6. 调用未知DLL中的导出函数[转]
  7. 机器学习中的距离/散度/熵
  8. PCA原理及代码实现
  9. 常用20个正则表达式
  10. Delphi XE开发 Android 开机自动启动