leetcode-56. Merge Intervals - Medium

descrition

Given a collection of intervals, merge all overlapping intervals.

  1. For example,
  2. Given [1,3],[2,6],[8,10],[15,18],
  3. return [1,6],[8,10],[15,18].

解析

两个思路,都比较有难度。注意算法正确性的证明。

方法 1 - 连通分支

通过的方法来解决。算法描述如下:

以每个间隔 interval 为图的顶点,如果两个 interval 是包含关系,即有其中一个被另一个包含,则使用无向边将两个顶点连接起来。由此图中每一个连通分量都可以进行合并。问题就转换成了如何求图的联通分量的问题。

此方法并非最优解,详细参考官网的 solution。这里重点介绍方法 2.

方法 2

算法描述:

令 ans 结果返回数组,istart, iend 分别表示当前 interval 的起止。

对于 intervals[] 数组:

  • 预处理:根据其起点,即 intervals[i].start 对 intervals 进行非递减有序排序。
  • 初始化:istart = intervals[0].start, iend = intervals[0].end
  • 循环执行以下步骤( i = [1, ..., n-1]):
    • 如果 intervals[i].start <= end:说明当前的 intervals[i] 可以被合并,此时更新 iend = max(iend, intervals[i].end),interval.end 不是有序的,因此要取两段间的最大值最为结尾。
    • 否则:说明当前的 intervals[i] 不能被合并,则 (istart, iend) 形成一个新的被加入到 ans 中,并更新 istart = intervals[i].start, iend = intervals[i].end
  • 注意最后一次 (istart, iend) 加入到 ans 中。

正确性证明:

使用反证法进行证明。

假设:以上算法不能将某些本应被合并的 interval 进行合并。

根据假设,则说明存在以下情况: 3 个下标,i, j, k,不失一般性令 i < j < k,此时 intervals[i] 和 intervals[k] 可以合并,但 intervals[i] 和 intervals[j],intervals[j] 和 intervals[k] 都不能合并。(算法中只考虑了相邻的 interval,因此当该情况存在时不能被识别)。

由以上假设可以得到不等式:

  1. 由不能合并的条件得到:
  2. intervals[i].end < intervals[j].start
  3. intervals[j].end < intervals[k].start
  4. 由合并的条件得到:
  5. intervals[i].end >= intervals[k].start

根据 interval 的定义,有 intervals[j].start <= intervals[j].end,由此对以上不等式进行合并得到:

  1. intervals[i].end < intervals[j].start <= intervals[j].end < intervals[k].start
  2. ==> intervals[i].end < intervals[k].start
  3. 与条件 intervals[i].end >= intervals[k].start 矛盾。

综上,算法得到的结果是正确的。

复杂度分析

  • 时间复杂度-O(nlog(n)),取决于排序算法
  • 空间复杂度-O(1) 或 O(n),取决于排序算法是否可以原址完成。

code

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. struct Interval{
  6. int start;
  7. int end;
  8. Interval(): start(0), end(0) {}
  9. Interval(int s, int e): start(s), end(e) {}
  10. };
  11. class Solution{
  12. public:
  13. vector<Interval> merge(vector<Interval>& intervals){
  14. vector<Interval> ans;
  15. if(intervals.empty())
  16. return ans;
  17. // sort intervals in ascending by Interval.start
  18. sort(intervals.begin(), intervals.end(), comp);
  19. int istart = intervals[0].start; // the start of the current interval
  20. int iend = intervals[0].end; // the end of the current interval
  21. for(int i=1; i<intervals.size(); i++){
  22. if(intervals[i].start <= iend){
  23. iend = max(iend, intervals[i].end);
  24. }else{
  25. ans.push_back(Interval(istart, iend));
  26. istart = intervals[i].start;
  27. iend = intervals[i].end;
  28. }
  29. }
  30. // don't forget the last interval
  31. ans.push_back(Interval(istart, iend));
  32. return ans;
  33. }
  34. static bool comp(Interval int1, Interval int2){ // in ascending
  35. return int1.start < int2.start;
  36. }
  37. };
  38. int main()
  39. {
  40. return 0;
  41. }

[array] leetcode-56. Merge Intervals - Medium的更多相关文章

  1. leetcode 56. Merge Intervals 、57. Insert Interval

    56. Merge Intervals是一个无序的,需要将整体合并:57. Insert Interval是一个本身有序的且已经合并好的,需要将新的插入进这个已经合并好的然后合并成新的. 56. Me ...

  2. LeetCode: 56. Merge Intervals(Medium)

    1. 原题链接 https://leetcode.com/problems/merge-intervals/description/ 2. 题目要求 给定一个Interval对象集合,然后对重叠的区域 ...

  3. LeetCode 56. Merge Intervals (合并区间)

    Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...

  4. Leetcode#56 Merge Intervals

    原题地址 排序+合并,没啥好说的 第一次尝试C++的lambda表达式,有种写js的感觉,很神奇 c11就支持了lambda表达式,仔细想想,我学C++大概就是在09~10年,c11还没有发布,不得不 ...

  5. [LeetCode] 56. Merge Intervals 解题思路

    Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...

  6. [LeetCode] 56 - Merge Intervals 合并区间

    Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...

  7. [leetcode]56. Merge Intervals归并区间

    Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6],[8, ...

  8. [LeetCode] 56. Merge Intervals(vector sort)

    /** * Definition for an interval. * struct Interval { * int start; * int end; * Interval() : start(0 ...

  9. LeetCode 56. Merge Intervals 合并区间 (C++/Java)

    题目: Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6] ...

  10. [Leetcode][Python]56: Merge Intervals

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 56: Merge Intervalshttps://oj.leetcode. ...

随机推荐

  1. _2Python_注释命名等基本操作

    注释:注解,解释 主要用于在代码中给代码标识出相关的文字提示(提高代码的可读性)或调试程序,方便别人阅读和自己日后修改. Python中注释分为两类.单行注释:单行注释以#号开头,在一行内,#号后面的 ...

  2. 我的第一个python web开发框架(17)——产品管理

    这是后台管理系统最后一个功能,产品管理,它的接口与页面功能与上一章差不多. 获取产品列表接口 @get('/api/product/') def callback(): ""&qu ...

  3. azure备份虚拟机

    备份 azure虚拟机 提前创建了一个linux虚拟机,位置是chinaeast. 如果我们需要备份的虚拟机分别在中国东部和北部,那么需要在两个位置都创建备份库. 创建库 登录经典门户,新建-> ...

  4. Android视频编辑SDK--RDVECore来自锐动的无UI,高度抽象化API

    1 RDVECore功能概述 RDVECore是锐动推出的无UI,高度抽象化API的视频编辑SDK,支持以下功能: 1.1 丰富的编辑功能 RDVECore包含了丰富的基础功能,对于编辑中的视频.图片 ...

  5. Python函数篇(二)之递归函数、匿名函数及高阶函数

    1.全局变量和局部变量 一般定义在程序的最开始的变量称为函数变量,在子程序中定义的变量称为局部变量,可以简单的理解为,无缩进的为全局变量,有缩进的是局部变量,全局变量的作用域是整个程序,而局部变量的作 ...

  6. 04.redis集群+SSM整合使用

    redis集群+SSM整合使用 首先是创建redis-cluster文件夹: 因为redis最少需要6个节点(三主三从),为了更好的理解,我这里创建了两台虚拟机(192.168.0.109 192.1 ...

  7. Lonlife 1000 - Spoon Devil's 3-D Matrix

    1000 - Spoon Devil's 3-D Matrix Time Limit:1s Memory Limit:32MByte Submissions:208Solved:65 DESCRIPT ...

  8. 如何生成CA证书

    一般情况下,如果能找到可用的证书,就可以直接使用,只不过会因证书的某些信息不正确或与部署证书的主机不匹配而导致浏览器提示证书无效,但这并不影响使用.需要手工生成证书的情况有:找不到可用的证书需要配置双 ...

  9. springmvc关于前台日期作为实体类对象参数类型转换错误

    页面报错: 后台错误: Field error in object 'user' on field 'birthday': rejected value [2013-06-24]; codes [ty ...

  10. day2-Python基本数据类型介绍

    百度云连接 链接:https://pan.baidu.com/s/1hsGQx7m 密码:u07q