区间问题就是线段问题,常见的问题设计就是合并区间、找出区间的交集等。
这类问题的技巧有:排序+画图。
- 排序:按照起点进行升序,相同则按照终点降序;
- 画图:两个区间的相对位置有哪些,不同的相对位置该怎么处理。
一、区间覆盖问题(LC1288, Medium, 删除被覆盖区间)

算出被覆盖区间的数目,然后总数一减就是要的结果,关键:排序+画图观察3种覆盖情况。
class Solution {public int removeCoveredIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return o1[0]==o2[0] ? o2[1]-o1[1] : o1[0]-o2[0];}});int total = intervals.length; //总数int res = 0; //覆盖区间的数目int left = intervals[0][0];int right = intervals[0][1];for (int i=1; i<total; i++) {int[] inter = intervals[i];//三种情况//1、被覆盖if (left<=inter[0] && right>=inter[1]) {res++;}//2、合并有重叠区间if (right<inter[1]) {right = inter[1];}//3、没有交集if (inter[0] > right) {left = inter[0];right = inter[1];}}return total-res;}}
二、区间合并问题(LC56, Medium, 合并区间)

class Solution {public int[][] merge(int[][] intervals) {//排序Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] interval1, int[] interval2) {return interval1[0] - interval2[0];}});int m = intervals.length;int left = intervals[0][0], right = intervals[0][1];List<int[]> resList = new ArrayList<>();for (int i=1; i<=m; i++) {if (i == m) {resList.add(new int[] {left, right});//System.out.print(left + " " + right);break;}int[] inter = intervals[i];//重叠合并if (inter[0]>=left && inter[0]<=right) {right = Math.max(right, inter[1]);}if (inter[0] > right) {resList.add(new int[] {left, right});//System.out.print(left + " " + right);left = inter[0];right= inter[1];}}return resList.toArray(new int[resList.size()][]);}}
三、区间交集问题(LC986, Medium, 区间列表的交集 )

class Solution {public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {List<int[]> resList = new ArrayList<>();int i=0, j=0;int m=firstList.length, n=secondList.length;while (i<m && j<n) {int a1 = firstList[i][0], a2 = firstList[i][1]; //第一个区间的第i个小区间int b1 = secondList[j][0], b2 = secondList[j][1]; //第二个区间的第j个小区间//存在交集if (b2>=a1 && b1<=a2) {resList.add(new int[]{Math.max(a1, b1), Math.min(a2, b2)});}if (a2>b2) {j++;} else {i++;}}return resList.toArray(new int[resList.size()][]);}}
总结一下,区间类问题看起来都比较复杂,情况很多难以处理,但实际上通过观察各种不同情况之间的共性可以发现规律,用简洁的代码就能处理。
