题目描述
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例
1、
1 2 3
| 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]] 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
|
2、
1 2 3
| 输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
|
解题思路
从题目描述,这个题就是把给定的数组,如有重叠就组合到一起,直到所有的数组都无法重叠,然后输出所有的数组。这个题,常规的做法就是将每个数组先按第一个元素排序,然后将根据数组的第二个元素拿出来和后一个数组进行比较,根据结果来进行是否合并或者保留。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public int[][] merge(int[][] intervals) { if (intervals.length == 0) { return new int[0][2]; } Arrays.sort(intervals, new Comparator<int[]>() { public int compare(int[] interval1, int[] interval2) { return interval1[0] - interval2[0]; } }); List<int[]> merged = new ArrayList<int[]>(); for (int i = 0; i < intervals.length; ++i) { int L = intervals[i][0], R = intervals[i][1]; if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) { merged.add(new int[]{L, R}); } else { merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R); } } return merged.toArray(new int[merged.size()][]); }
|
我的思路是:
1、创建一个长度为n的数组box,n的值为给定的二维数组的数字的最大值。
2、然后遍历给定的数组,根据每一个一维数组元素,将其设为遍历box的起点和终点,并且把中间值设为1,起点设为1,终点设为2。(也可以设为其他值)
3、遍历所有的一维数组后,此时的box数组,将相当于,把所有覆盖的区间都设定了值。
4、再次遍历一维数组,把box中所有已经设定的值得区间的起点和终点记录下来即可。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| public int[][] merge1(int[][] intervals) { int max=0; for(int[] interval:intervals){ max= Math.max(max, interval[1]); } int[] ints=new int[max+1]; for(int[] interval:intervals){ for(int i=interval[0];i<interval[1];i++){ ints[i]=1; } ints[interval[1]]=ints[interval[1]]==1?1:2; }
Stack<Integer> left=new Stack<>(); Stack<Integer> right=new Stack<>(); for(int i=0;i<ints.length;i++){ if(i==0&&ints[i]==2){ left.push(i); right.push(i); continue; } if(i==0&&ints[i]==1){ left.push(i); continue; } if(ints[i]==1&&ints[i-1]==0){ left.push(i); continue; } if(ints[i]==1&&ints[i-1]==2){ left.push(i); continue; }
if(ints[i]==2&&ints[i-1]==0){ left.push(i); right.push(i); continue; }
if(ints[i]==2&&ints[i-1]==2){ left.push(i); right.push(i); continue; } if(ints[i]==2&&ints[i-1]==1){ right.push(i); continue; } if(i==ints.length-1&&ints[i]==2){ right.push(i); } } int leng=right.size(); int[][] result=new int[leng][2]; for(int i=0;i<result.length;i++){ result[i][0]=left.pop(); result[i][1]=right.pop(); } return result; }
|
看这两种思路的时间可能第二种的时间更短(第一种的方法主要浪费在排序上了),但第二种思路不太好想,而且特殊情况需要考虑完全,才能通过,所以大家可以根据实际情况来选择合适的方法解题。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals