代码随想录总结
406.根据身高重建队列
452.用最少数量的箭引爆气球
435.无重叠区间
763.划分字母区间
56.合并区间
区间问题一般都要排序,这时候要考虑是按左边排序还是按右边排序。
举例:左边升序,左边相等则右边降序排序
Arrays.sort(name, (o1,o2) ->{
if(o1[0] == o2[0]) return o2[1] -o1[1];
return o1[0] - o2[0];
} );
如果左边相等右边也是升序的话,不用if判断条件,此时
Arrays.sort(name, (o1,o2) ->{
return o1[0] - o2[0];
} );
有的题目使用减法会产生数据溢出,所以只按照一边排序的话,使用Integer中的排序方法
Arrays.sort(name, (o1,o2) -> Integer.compare(o1[0],o2[0]));
本题的解题方法是按照左边排序,也就是按照身高排序,身高相等的按照右边升序。按照身高降序排序后,每个人前面的人一定比他高或者身高相等,此时可以按照右边把他们插入到对应的位置。
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people,(a,b)-> {
if(a[0] == b[0]) return a[1]-b[1];
return b[0] - a[0];
});
LinkedList<int[]> list = new LinkedList<>();
for(int[] p :people){
p[1]是位置,按照位置插入链表集合中
list.add(pos,i) 把i插入到集合中pos位置
list.add(p[1],p);
}
把集合转为二维数组
return list.toArray(new int[people.length][]);
}
按照左边进行升序排序,重叠气球右边最小值之前的区间一定需要一支弓箭。
public int findMinArrowShots(int[][] points) {
int res = 1;
Arrays.sort(points,(x1,x2) -> Integer.compare(x1[0],x2[0]));
for(int i = 1;i<points.length;i++){
if(points[i][0] > points[i-1][1]){
res++;
}else{
当区间左边小于等于前一个区间右边时,会被射爆。
更新该区间右边界为当前和前面区间右边界最小值,表示弓箭从最小值这里射出
points[i][1] = Math.min(points[i][1],points[i-1][1]);
}
}
return res;
}
此题按照右边区间排序比较好理解,让右边界越小,留给后面区间的位置就越大
public int eraseOverlapIntervals(int[][] intervals) {
int res = 0;
Arrays.sort(intervals,(o1,o2) -> Integer.compare(o1[1],o2[1]));
for(int i= 0;i<intervals.length-1;i++){
if(intervals[i][1] > intervals[i+1][0]){
表示移除了i+1那个区间,让i+1区间的右边界等于两个区间右边界的最小值。
res++;
其实不用min比较也可以因为一开始就按照右边界排序了,i+1右边界一定大于或等于i的右边界
intervals[i+1][1] = Math.min(intervals[i+1][1],intervals[i][1]);
}
}
return res;
}