前言
今日打卡算法题,抽到合并区间,以其为载体,展示我的个人解决问题的理解。
一、合并区间
二、解
1、idea
target:将重复的区间合并。
个人认为抓核心问题的能力是前置能力:1-什么是重复区间?2-合并成什么样子?
1-什么是重复区间?设区间[a,b]和[c,d],当 a > d || b < c 时不重复;反之a <= d && b >= c则两区间重复。
2-合并成什么样子?有了判定重复区间的条件,则需合并成[min(a,c),max(b,d)]
实际方案一:暴力法:把两两区间按上面方式合并,新区间加入list,合并之后的2个区间remove掉。O(N)/O(N)
个人认为:套路是工具,用于解决我们找到的核心问题。
存在套路:像这种二维数组有一个套路就是,多半需要第一二个元素进行顺序/逆序。
实际方案二:排序法:为了防止每次要寻找所有区间来合并,将区间排序,合并过了的区间自然就不考虑了,剩下的区间也只需一个个的合并即可。(利用人为创造的有序性。)
2、code
package everyday.medium;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
// 区间合并
public class Merge {
/*
target:将重复的区间合并。
个人认为抓核心问题的能力是前置能力:1-什么是重复区间?2-合并成什么样子?
1-什么是重复区间?设区间[a,b]和[c,d],当 a > d || b < c 时不重复;反之a <= d && b >= c则两区间重复。
2-合并成什么样子?有了判定重复区间的条件,则需合并成[min(a,c),max(b,d)]
暴力法:把两两区间按上面方式合并,新区间加入list,合并之后的2个区间remove掉。O(N)/O(N)
个人认为:套路是工具,用于解决我们找到的核心问题。
存在套路:像这种二维数组有一个套路就是,多半需要第一二个元素进行顺序/逆序。
排序法:为了防止每次要寻找所有区间来合并,将区间排序,合并过了的区间自然就不考虑了,剩下的区间也只需一个个的合并即可。(利用人为创造的有序性。)
*/
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (o1, o2) -> {
if (o1[0] != o2[0]) return o1[0] - o2[0];
return o1[1] - o2[1];
});
List<int[]> ans = new ArrayList<>();
int[] cur = new int[]{intervals[0][0], intervals[0][1]};
for (int i = 1; i < intervals.length; i++) {
int a = cur[0], b = cur[1], c = intervals[i][0], d = intervals[i][1];
if (a > d || b < c) {
ans.add(new int[]{a, b});
cur[0] = c;
cur[1] = d;
continue;
}
cur[1] = Math.max(b, d);
}
ans.add(cur);
return ans.toArray(new int[0][]);
}
}
总结
- 抓核心问题,解决方案都是围绕解决核心问题转。
- 二维数组的套路,需要先排序,有了有序性,则联想到双指针/滑动窗口/二分法等。
参考文献
[1] LeetCode 56.合并区间