题目链接】
力扣(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中相交的情况,代码就会简洁清晰很多。