The problem:
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
Assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals [1,3],[6,9]
, insert and merge in as [2,5]
[1,5],[6,9]
.
Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16]
, insert and merge in as [4,9]
[1,2],[3,10],[12,16]
.
This is because, the new interval [4,9]
overlaps with [3,5],[6,7],[8,10]
.
My First Solution:
The logic behind this solution is complex and errors prone! It ' s because I has not totally understand the rational behind this problem.
Public classSolution { Publiclist<interval> Insert (list<interval>intervals, Interval newinterval) {ArrayList<Interval> ret =NewArraylist<interval> (); if(Intervals = =NULL) { //return Ret.add (newinterval);Ret.add (NewInterval); returnret; } if(NewInterval = =NULL) returnintervals; Interval Pre=NewInterval (Newinterval.start, newinterval.end); BooleanFlag =false;//indicate if the new Interval has already been added for(inti = 0; I < intervals.size (); i++) {Interval cur=Intervals.get (i); if((cur.start>=pre.start&&cur.start<=pre.end) | | (cur.end>=pre.start&&cur.end<=pre.end) | | (Cur.end>=pre.end&&pre.start>=cur.start)) {//overlapping happensPre.start = Pre.start < Cur.start?Pre.start:cur.start; Pre.end= pre.end > Cur.end?Pre.end:cur.end; } Else { if(Pre.end < Cur.start && flag! =true) {//The pre interval ' s range is over!Ret.add (PRE); Flag=true;//casue I put off the add of the answer at next independent interval} ret.add (cur); } } if(Flag! =true)//In the interval!Ret.add (PRE); returnret; }}
A more Elegant!!!
A Advanced Analysis
The idea behind Thissolution is simple and great, you must master related skills. The key idea: [...] [ ] [] [] [][]we should able to figure out the first and last overlapping intervals with newinterval.1. How do I find out the first?At the first collision interval, as shown above, the start boundary must less than the end boundary of the first. We use the contradiction as loop condition:before the first collision, the intervals end boundary must ahead of the Newin Terval' s start boundary. Use of this property, we could reach the first collision window. Note the loop condition.inti = 0; while(I<intervals.size () && (Newinterval.start>intervals.get (i). end)) {//If not collision, we move on.Ret.add (Intervals.get (i)); I++;}2. As the same, once we dectect the first collision, begin from the interval, all collision interval ' s start boundary must LessThan the NewInterval ' s start boundary. while(I<intervals.size () && (newinterval.end>=Intervals.get (i). Start)) {Newinterval.end= newinterval.end > Intervals.get (i). End?NewInterval.end:intervals.get (i). end; I++;} Since we detect the first overlapping interval, until we reach the last interval, we keep on merge newinterval through fol lowing ways: ...if(I < intervals.size ()) {//must not exceed the end!!!Newinterval.start = Newinterval.start < Intervals.get (i). Start?NewInterval.start:intervals.get (i). Start; while(I<intervals.size () && (newinterval.end>=Intervals.get (i). Start)) {Newinterval.end= newinterval.end > Intervals.get (i). End?NewInterval.end:intervals.get (i). end; I++;} the whileLoop is because this, the checking codition is "newinterval.end>=intervals.get (i). Start)" When means when the interval Meets the condition of collision, we merge it into the collision interval.
The solution:
Public classSolution { Publiclist<interval> Insert (list<interval>intervals, Interval newinterval) {ArrayList<Interval> ret =NewArraylist<interval> (); if(Intervals = =NULL|| Intervals.size () = = 0) {ret.add (newinterval); returnret; } if(NewInterval = =NULL) returnintervals; inti = 0; while(I<intervals.size () && (newinterval.start>Intervals.get (i). end)) {Ret.add (Intervals.get (i)); I++; } if(I < intervals.size ()) {//must not exceed the end!!!Newinterval.start = Newinterval.start < Intervals.get (i). Start?NewInterval.start:intervals.get (i). Start; } while(I<intervals.size () && (newinterval.end>=Intervals.get (i). Start)) {Newinterval.end= newinterval.end > Intervals.get (i). End?NewInterval.end:intervals.get (i). end; I++; } ret.add (NewInterval); while(i<intervals.size ()) {Ret.add (Intervals.get (i)); I++; } returnret; }}
[leetcode#57] Insert Interval