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. markdown简述

     前端开发的工具    编辑器:   1. 轻量级的,依靠插件:sublime:atom(github):vs code(miscrosaft)   2. 集成的:DW:webstorm:hbuild ...

  2. java 之 原型模式(大话设计模式)

    原型模式,在笔者理解看来就是克隆,当我们在创建第一个对象时,已经给对象赋值完毕,此时我们需要一个当前对象的副本,如果没有原型模式,我们会再次创建一个对象,然后后二次赋值,保证两个对象完全一致, 这样我 ...

  3. DP 网易内推:合唱团

    链接:https://www.nowcoder.com/questionTerminal/661c49118ca241909add3a11c96408c8来源:牛客网 [编程题]合唱团 热度指数:18 ...

  4. eclipse环境下基于已构建struts2项目整合spring+hibernate

    本文是基于已构建的struts2项目基础上整合 spring+hibernate,若读者还不熟悉struts2项目,请先阅读 eclipse环境下基于tomcat-7.0.82构建struts2项目 ...

  5. 关于RDLC报表打印预览界面显示页码问号的问题

    原来在reportview中,vs2010新增了一个属性,pageCountMode,默认的Estimate,提供估算的页数,另外一个属性Actual,提供实际的页数.

  6. 面试相关-转载-well,yzl——持续更新

    转载yl,yzl大神的面经,顺便自己复习一下专业课的内容 操作系统相关: 什么是进程, 什么是线程.它们之间的区别和联系. 进程管理内存资源+运行过程, 线程只管理运行过程, 线程要在进程提供的资源基 ...

  7. android studio 目录结构讲解

    android studio 目录结构讲解 src 毫无疑问,src目录是放置我们所有 Java代码的地方,它在这里的含义和普通 Java 项目下的 src目录是完全一样的,展开之后你将看到我们刚才创 ...

  8. 学习使用azure CLI创建linux环境

    学习使用azure CLI创建linux环境 选用了容器的方法来登录 docker run -it microsoft/azure-cli 进入交互界面后登录到我的订阅 azure login -e ...

  9. JavaScript实现动画效果

    说到JavaScript实现动画效果,不得不想到两个函数,setTimeout和setInterval. setTimeout的常用的使用方法为 setTimeout(callback, delay) ...

  10. 判断是否AVL平衡二叉书

    #include<iostream> #include<vector> #include<stack> #include<string> #includ ...