思路: 这道题我写了一天,真正落实了一杯茶一包烟,一道算法写一天的思想。思路是sort。其实我一下就想到这个方法了。但是sort之后我debug了一天的东西,标答两行就写完了。well。。。其实思路真的很简单,sort完之后数组中可以merge的区间都会紧紧挨在一起,这时候我们遍历数组,和前一个区间比较,看看能不能merge就行。标答这边用到一个linkedlist用来存储答案。标答唯一巧妙的地方是linedlist中的对象类型是int[]。这是我没想到的,我以为类型不能是数组。具体的思路可以看lc approach 2,和我的思路基本一模一样。建议复盘的时候直接忽略我的代码,肯定是看不懂的,别费力气了。不谈了,累死我了,直接上代码:
class Solution {
public int[][] merge(int[][] intervals) {
int[][] hh = new int[0][0];
if(intervals.length == 0) return hh;
if(intervals.length == 1) return intervals;
int m = intervals.length; // nums of intervals
int[][] res = new int[m][2];
Arrays.sort(intervals, (o1, o2) -> o1[0] - o2[0]);
int max = intervals[0][1];
for(int i = 0; i < m - 1; i++){
if(intervals[i + 1][0] == intervals[i][0]){
max = Math.max(intervals[i + 1][1], max);
if(i == m - 2){
res[i + 1][0] = intervals[i][0];
res[i + 1][1] = max;
}
}else{
res[i][0] = intervals[i][0];
res[i][1] = max;
if(max == 0){
res[i][0] = Integer.MAX_VALUE;
res[i][1] = Integer.MAX_VALUE;
}
max = intervals[i + 1][1];
if(i == m - 2){
res[i + 1][0] = intervals[i + 1][0];
res[i + 1][1] = max;
}
}
}
List<Integer> list = new ArrayList<>();
for(int i = 0; i < m; i++){
if(res[i][0] == Integer.MAX_VALUE && res[i][1] == Integer.MAX_VALUE){
list.add(0);
list.add(0);
}else if(res[i][0] != 0 || res[i][1] != 0){
list.add(res[i][0]);
list.add(res[i][1]);
}
}
int size = list.size();
int temp = list.get(size - 1);
list.set(size - 1, Integer.MAX_VALUE);
int endFlag = Integer.MAX_VALUE;
for(int i = 0; i < Integer.MAX_VALUE; i = i + 2){
if(list.size() == 2){
list.set(1,temp);
break;
}
if(list.get(i + 3) == endFlag){
list.set(i + 3, temp);
int check = list.get(i + 1);
if(list.get(i + 3) > check && list.get(i + 2) <= check){
list.set(i + 1,list.get(i + 3));
list.remove(i + 2);
list.remove(i + 2);
}else if(list.get(i + 3) <= check){
list.remove(i + 2);
list.remove(i + 2);
}
break;
}
int check = list.get(i + 1);
if(list.get(i + 3) > check && list.get(i + 2) <= check){
list.set(i + 1,list.get(i + 3));
list.remove(i + 2);
list.remove(i + 2);
i = i - 2;
}else if(list.get(i + 3) <= check){
list.remove(i + 2);
list.remove(i + 2);
i = i - 2;
}
}
int[][] output = new int[list.size() / 2][2];
for(int i = 0; i < list.size() - 1; i = i + 2){
output[i / 2][0] = list.get(i);
output[i / 2][1] = list.get(i + 1);
}
return output;
}
}
我写了一天的垃圾代码,当然要放在前面。下面才展示标答approach2:
class Solution {
private class IntervalComparator implements Comparator<int[]> {
@Override
public int compare(int[] a, int[] b) {
return a[0] < b[0] ? -1 : a[0] == b[0] ? 0 : 1;
}
}
public int[][] merge(int[][] intervals) {
Collections.sort(Arrays.asList(intervals), new IntervalComparator());
LinkedList<int[]> merged = new LinkedList<>();
for (int[] interval : intervals) {
// if the list of merged intervals is empty or if the current
// interval does not overlap with the previous, simply append it.
if (merged.isEmpty() || merged.getLast()[1] < interval[0]) {
merged.add(interval);
}
// otherwise, there is overlap, so we merge the current and previous
// intervals.
else {
merged.getLast()[1] = Math.max(merged.getLast()[1], interval[1]);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
总结:
- 二维数组真的有很多奇怪的特点。
- 去了解二维数组的排序
- list中对象类型可以是数组!!