Merge Intervals
来源:互联网 发布:智能停车场收费软件 编辑:程序博客网 时间:2024/05/22 07:58
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]
.
解法一:从头开始进行两两合并
/** * Definition for an interval. * public class Interval { * int start; * int end; * Interval() { start = 0; end = 0; } * Interval(int s, int e) { start = s; end = e; } * } */class Interval implements Comparable<Interval>{int start;int end;Interval() { start = 0; end = 0; }Interval(int s, int e) { start = s; end = e; }public int compareTo(Interval o){return this.start - o.start;}}public class Solution { public static List<Interval> merge(List<Interval> intervals){Collections.sort(intervals);List<Interval> result = new ArrayList<Interval>(); int length = intervals.size(); if(length <= 1) return intervals; Interval first = intervals.get(0),second = new Interval(); for(int i = 1; i < length; i++) { second = intervals.get(i); if(second.start > first.end) { result.add(first); first = second; } else { first.end = Math.max(first.end, second.end);} } //最后一次合并 result.add(first); return result; }}
解法二:
区间合并 和 求最长区间 一样,关键在于如何记录区间信息,能够降低复杂度。
最简单的思路是用一个bool数组,记录区间中的每一位是否被覆盖。
例如:
intervals: [1, 4] [8, 9] [20, 30] [7, 14] [2, 9]
设一个数组 bool f[30],初始化全部为false
[1, 4]就把f[1]..f[4]全部置为true
其他区间一次类推,最后扫描f数组,就能得到区间合并的结果。
这种做法对于小数据还行,大数据会超市。
这样做,存在很多重复工作,例如[1, 4] [8, 9] [7, 14] [2, 9]这四个区间,会反复将f[2] f[3] f[4][ f[5] f[6] f[7] f[8] f[9]设为true。
所以,我们需要考虑的是如何去除重复的工作。实际上,两个端点就能描述出一个区间,关键在于如何标记出两个端点,让我们在扫描时能够知道这个区间被覆盖。
一个很巧妙的做法就是进入一个区间就加1,出一个区间就减1,如果数值大于0,说明当前处于一个区间中。
还是以刚刚的intervals为例。
设数组 int l[30], r[30],初始化全部为0
[1, 4]:l[1]++, r[4]--
[8, 9]:l[8]++, r[9]--
...
扫描时,用一个count记录,每次:
count += l[i],如果count>0说明i处于一个区间中
count -= r[i],如果count==0说明i是一个区间的尾端点
public static List<Interval> merge(List<Interval> intervals) { List<Interval> result = new ArrayList<Interval>(); int length = intervals.size(); if(length <= 1) return intervals; int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE; for(int i = 0;i < length; i++) { Interval tmp = intervals.get(i); max = Math.max(max, tmp.end); min = Math.min(min, tmp.start); } int[] left = new int[max + 1]; int[] right = new int[max + 1]; for(int i = 0;i < length; i++) { Interval tmp = intervals.get(i); left[tmp.start]++; right[tmp.end]--; } int start = -1, count = 0; for(int i = min; i <= max; i++) { count += left[i]; if(count > 0 && start == -1) start = i; count += right[i]; if(count == 0 && start != -1) { result.add(new Interval(start, i)); start = -1; } } return result; }
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- merge intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- Merge Intervals
- poj 3264 Balanced Lineup ST+线段树
- hdu 1394 Minimum Inversion Number
- 最长上升子序列(LIS)长度的O(n^2)与O(nlogn)算法
- iOS 监测应用是否是第一次打开&监测应用是否已经更新
- 高桥和低桥
- Merge Intervals
- Problem 8:Largest product in a series
- .NET配置文件
- 2012长春站K题 || hdu4430 枚举+二分
- hibernate向mysql插入数据乱码问题
- fstream
- ruby on rails: bundle install 耗时太长
- const修饰指针的一些细微差别
- LeetCode: Divide Two Integers