题目链接】
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
【解题代码】
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> intervalList = new ArrayList<>();
boolean newIntervalInsert = false;
for (int i = 0; i < intervals.length; i++) {
if (!newIntervalInsert) {
int r = intervalCompare(newInterval, intervals[i]);
if (r == 0) {
intervalList.add(newInterval);
intervalList.add(intervals[i]);
newIntervalInsert = true;
} else if (r == 4) {
intervalList.add(intervals[i]);
} else {
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
}
} else {
intervalList.add(intervals[i]);
}
}
if (!newIntervalInsert) {
intervalList.add(newInterval);
}
int[][] result = new int[intervalList.size()][2];
for (int i = 0; i < intervalList.size(); i++) {
result[i] = intervalList.get(i);
}
return result;
}
private int intervalCompare(int[] interval1, int[] interval2) {
if (interval1[1] < interval2[0]) return 0;
if (interval1[0] > interval2[1]) return 4;
if (interval1[0] <= interval2[0]) {
return interval1[1] <= interval2[1] ? 1 : 5;
} else {
return interval1[1] <= interval2[0] ? 2 : 3;
}
}
}
【解题步骤】
- 插入区间算法关键是解决两个区间interval1和interval2的位置判断,经过分析可得两个区间位置有以下6种情况:
- interval1在interval2左外部,即interval1[1] < interval2[0];
- interval1与interval2左相交,即interval1[0] <= interval2[0]&&interval1[1]> interval2[0] interval1[1] <= interval2[1];
- interval1被interval2包含,即interval1[0] > interval2[0]&&iinterval1[1] < interval2[1];
- interval1与interval2右相交,即interval1[0] > interval2[0]&&interval1[0]< interval2[1] interval1[1] > interval2[1];
- interval1在interval2右外部,即interval1[0] > interval2[1];
- interval1包含interval2,即interval1[0] < interval2[0]&&iinterval1[1] >interval2[1];
private int intervalCompare(int[] interval1, int[] interval2) { if (interval1[1] < interval2[0]) return 0; if (interval1[0] > interval2[1]) return 4; if (interval1[0] <= interval2[0]) { return interval1[1] <= interval2[1] ? 1 : 5; } else { return interval1[1] <= interval2[0] ? 2 : 3; } }
- 上面6种情况又可以分为三类:
- interval1在interval2左外部
- interval1与interval2相交
- interval1在interval2右外部
- 根据上面三种位置分类,newInterval与所有intervals[i]依次分别处理:
- newInterval在intervals[i]左外部:将newInterval和intervals[i]加入结果集,然后将后续所有intervals[i]加入结果集即可;
- newInterval与intervals[i]相交:将newInterval与intervals[i]合并,并继续处理后续intervals[i];
- newInterval在interval[i]右外部,将interval[i]加入结果集,并继续处理后续intervals[i];
for (int i = 0; i < intervals.length; i++) { if (!newIntervalInsert) { int r = intervalCompare(newInterval, intervals[i]); if (r == 0) { intervalList.add(newInterval); intervalList.add(intervals[i]); newIntervalInsert = true; } else if (r == 4) { intervalList.add(intervals[i]); } else { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); } } else { intervalList.add(intervals[i]); } }
- 收尾处理:判断下newInterval是否已经加入结果集,如果还没添加,则添加一下即可
if (!newIntervalInsert) { intervalList.add(newInterval); }
- 最后将list类型的结果转成数组返回即可
int[][] result = new int[intervalList.size()][2]; for (int i = 0; i < intervalList.size(); i++) { result[i] = intervalList.get(i); } return result;
【思路总结】
- 逻辑思维,逻辑思维,逻辑思维,重要的事情说三遍,算法处理一定要相关业务逻辑上想清楚;
- intervalCompare函数编写时有技巧,先把左右两种外部不相交的情况,然后再处理剩余4中相交的情况,代码就会简洁清晰很多。
- LeetCode解题之前,一定不要看题解,看了就“破功”了!