动态合并的问题:
通过遍历intervals,和newInterval对比:
1 如果比newInterval小:直接加入新集合
2 如果有overlap,动态改变newInterval为新的区间,继续合并
3 如果比newInterval大:加入newInterval到新集合,然后把newInterval更新为当前对象
之前在做第三步时,不懂得用动态改变newInterval的方法,而是用一个flag来做,后来看了http://wmjjmw.blogspot.com/2013/03/leetcode-insert-interval.html 才知道原来有如此巧妙的方法!
package Level4; import java.util.ArrayList; import Utility.Interval; /** * Insert Interval * * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. Example 2: Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. * */ public class S57 { public static void main(String[] args) { ArrayList<Interval> intervals = new ArrayList<Interval>(); intervals.add(new Interval(1, 2)); intervals.add(new Interval(3, 5)); intervals.add(new Interval(6, 7)); intervals.add(new Interval(8, 10)); intervals.add(new Interval(12, 16)); Interval newInterval = new Interval(4, 9); System.out.println(insert(intervals, newInterval)); } public static ArrayList<Interval> insert(ArrayList<Interval> intervals, Interval newInterval) { ArrayList<Interval> ret = new ArrayList<Interval>(); Interval merged = newInterval; // boolean added = false; for(int i=0; i<intervals.size(); i++){ Interval cur = intervals.get(i); if(cur.end < merged.start){ // 说明cur在merged前面,直接加入 ret.add(cur); } // 说明cur在merged后面,说明之后的更不可能和merged有交集,所以可以加入merged,并改变merged对象为cur对象! else if(cur.start > merged.end){ // if(!added){ // ret.add(merged); // added = true; // } // ret.add(cur); ret.add(merged); merged = cur; // 动态改变要合并的对象为cur对象! }else{ // overlap部分,动态扩展merged int min = Math.min(cur.start, merged.start); int max = Math.max(cur.end, merged.end); merged = new Interval(min, max); } } // if(!added){ // ret.add(merged); // } ret.add(merged); // 最后加入merged Interval return ret; } }
Second try:
import java.util.ArrayList; /* Insert Interval Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. Example 2: Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. */ public class InsertInterval { public static void main(String[] args) { } public ArrayList<Interval> insert(ArrayList<Interval> intervals, Interval newInterval) { ArrayList<Interval> ret = new ArrayList<Interval>(); Interval merged = newInterval; for(int i=0; i<intervals.size(); i++){ Interval cur = intervals.get(i); if(cur.end < merged.start){ // 情况1,cur在merged的前面 ret.add(cur); } else if(merged.end < cur.start){ //情况2,cur在merged的后面 ret.add(merged); merged = cur; } else{ // 这部分要最后写,因为情况最复杂 int min = Math.min(cur.start, merged.start); int max = Math.max(cur.end, merged.end); merged = new Interval(min, max); } } ret.add(merged); return ret; } public static class Interval{ int start; int end; public Interval(){ start = 0; end = 0; } public Interval(int s, int e){ start = s; end = e; } } }
关键是画图,画出几种可能
先根据cur.start和newInterval.start的两种相对位置,来区分,然后再考虑具体位置,再细分两种。所以总共就是4种组合:
/** * 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; } * } */ public class Solution { public List<Interval> insert(List<Interval> intervals, Interval newInterval) { List<Interval> ret = new ArrayList<Interval>(); for(int i=0; i<intervals.size(); i++) { Interval cur = intervals.get(i); if(newInterval.start <= cur.start) { // newInterval's start is ahead of cur's start if(cur.start <= newInterval.end) { newInterval = new Interval(Math.min(newInterval.start, cur.start), Math.max(newInterval.end, cur.end)); } else { ret.add(newInterval); newInterval = cur; } } else { // cur's start is ahead of newInterval's start if(newInterval.start <= cur.end) { newInterval = new Interval(Math.min(newInterval.start, cur.start), Math.max(newInterval.end, cur.end)); } else { ret.add(cur); } } } ret.add(newInterval); return ret; } }