/* * 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]. */ /* * source code from blog: * http://simpleandstupid.com/2014/10/29/insert-interval-leetcode-%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/ * * */ public static ArrayList insert(ArrayList intervals, Interval newInterval) { ArrayList result = new ArrayList(); foreach (Interval interval in intervals) { if(interval.end < newInterval.start){ result.Add(interval); }else if(interval.start > newInterval.end){ result.Add(newInterval); newInterval = interval; }else if(interval.end >= newInterval.start || interval.start <= newInterval.end){ newInterval = new Interval( Math.Min(interval.start, newInterval.start), Math.Max(newInterval.end, interval.end)); } } result.Add(newInterval); return result; }
/* * Julia's comment: * 1. First, review the thought process: * Go over all the intervals one by one; In each iteration, * compare to the two intervals. * * 3 cases: * case 1: the interval ends before new interval starts -> * action: add the interval to the return result container * * case 2: the interval starts after new interval ends -> * action: add new interval to the return result container, * and set the interval as the new one * * case 3: the interval overlaps with new interval -> * action: merge two intervals, and save it as * new interval. * * 2. Secondly, the code has a few of issues. Let us improve the code. * 1. Abstract code, no more interval word in variable name; * 2. Make it easy to go over test cases; * Case stands out easily in the code. * Code is more testable. * * step 1: Make the function a simple math, not interval business. * step 2: Two intervals, R1 (stands for come and go one in the loop), * R2 (stand for extra range for next iteration). * * tip: R2 one can be understandable by going through the test cases: * Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16] * R1 R2 * [1,2] [4,9] -> R1 is added to return container: {[1,2]} * [3,5] [4,9] -> R1 and R2 overlaps, then, R2 = [3,9] * [6,7] [3,9] -> R1 and R2 overlaps, then, R2 = [3,9] * [8,10] [3,9] -> R1 and R2 overlaps, then, R2 = [3, 10] * [12, 16] [3,10] -> R2 is added to return container, so it is {[1,2],[3,10]}; * R2 = R1 = [12, 16] * Now add R2 to the return container, so the result: {[1,2], [3,10], [12, 16]} */ public static ArrayList insert_B(ArrayList arry, Interval newOne) { ArrayList result = new ArrayList(); Interval R2 = newOne; foreach (Interval R_i in arry) { Interval R1 = R_i; // Range 1, come and go bool isR1R2 = R1.end < R2.start; // R1 is before R2 bool isR2R1 = R1.start > R2.end; // R2 is before R1 bool needMerge = R1.end >= R2.start || // R1 overlaps R2 R1.start <= R2.end; if (isR1R2) { result.Add(R1); } else if (isR2R1) { result.Add(R2); R2 = R1; } else if (needMerge) { R2 = new Interval( Math.Min(R1.start, R2.start), Math.Max(R1.end, R2.end)); } } result.Add(R2); return result; }