leetcode-56. Merge Intervals - Medium

descrition

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
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,因此当该情况存在时不能被识别)。

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

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

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

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

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

复杂度分析

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

code

#include <iostream>
#include <vector>
#include <algorithm> using namespace std; struct Interval{
int start;
int end;
Interval(): start(0), end(0) {}
Interval(int s, int e): start(s), end(e) {}
}; class Solution{
public:
vector<Interval> merge(vector<Interval>& intervals){
vector<Interval> ans;
if(intervals.empty())
return ans; // sort intervals in ascending by Interval.start
sort(intervals.begin(), intervals.end(), comp); int istart = intervals[0].start; // the start of the current interval
int iend = intervals[0].end; // the end of the current interval
for(int i=1; i<intervals.size(); i++){
if(intervals[i].start <= iend){
iend = max(iend, intervals[i].end);
}else{
ans.push_back(Interval(istart, iend));
istart = intervals[i].start;
iend = intervals[i].end;
}
} // don't forget the last interval
ans.push_back(Interval(istart, iend)); return ans;
} static bool comp(Interval int1, Interval int2){ // in ascending
return int1.start < int2.start;
}
}; int main()
{
return 0;
}

[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. ligerUI---下拉菜单(menubar)动态显示(从后台获取数据)

    写在前面: ligerui的下拉菜单是有点丑的,这也是没有办法的事........这里主要记录下,如何从后台获取数据进行菜单显示. 有两种方式:1.使用json数组来动态添加  2.字符串拼接.  其 ...

  2. Chrome 浏览器报 filed to load resource:net err cache read failure 错误:

    在IE/FF下没有该错误提示,但在Chrome下命令行出现如下错误信息: Failed to load resource: net::ERR_CACHE_MISS 该问题是Chrome浏览器开发工具的 ...

  3. 说说缓存,说说Redis

    无论是客户端还是服务端,缓存都是必不可少的一种提升用户体验的策略,大家在平时开发中,有意无意都会用到缓存,比如说 Android 开发的同学们,所有的图片框架,基本都有用到缓存技术,服务端那就完全不用 ...

  4. android 开源收藏

    第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Pro ...

  5. JS 函数节流和去抖

    1.什么是节流和去抖? 节流.就是拧紧水龙头让水少流一点,但是不是不让水流了.想象一下在现实生活中有时候我们需要接一桶水,接水的同时不想一直站在那等着,可能要离开一会去干一点别的事请,让水差不多流满一 ...

  6. pyhton 关于 configparser 配置 模块 实践使用中碰到的坑

    今天做一个ATM的练习,想要用configparser模块,写一个配置文件,存放用户信息. 结果状况连连,叫苦不迭. 我用configparser模块,想要对配置文件,进行读.写.改.查 功能. 其中 ...

  7. thinkphp 使用插件异步上传图片或者文件

    使用tp做一些上传的功能,的确挺方便.但是在一些特殊情况下无法单独的使用tp的上传功能, 或者需要做一些比较酷炫的上传效果,这里就需要用到框架了. 我在这里使用的是uploadify上传插件. 首先需 ...

  8. Scala入门系列(一):基础语法

    Scala基础语法 Scala与JAVA的关系 Scala是基于Java虚拟机,也就是JVM的一门编程语言,所有Scala的代码都需要经过编译为字节码,然后交由Java虚拟机来运行. 所以Scala和 ...

  9. ConcurrentHashMap\HashMap put操作时key为什么要rehash

    参考java并发编程的艺术一书中,对ConcurrentHashMap的讲解 ConcurrentHashMap使用的是分段锁Segment来保证不同的Segment区域互相不干扰,不存在锁竞争关系, ...

  10. .9-浅析webpack源码之NodeEnvironmentPlugin模块总览

    介绍Compiler的构造比较无趣,不如先过后面的,在用到compiler的时候再做讲解. 这一节主要讲这行代码: // 不管这里 compiler = new Compiler(); compile ...