题目
https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/
题解
重叠区间问题可以总结为在坐标轴上若干个位置为 (start(i),end(i)) 的区间,要求求解这些区间中有多少个不重叠区间,或者合并重叠的区间。
对于重叠区间问题,海外版评论区有人总结了模板,见 A Concise Template for “Overlapping Interval Problem”
该问题分两类:第一类求重叠区间个数(leetcode 452,435),第二类求合并后的区间(leetcode 56,763)。
对于第一类问题,通常按照end排序,维护一个end变量即可。
对于第二类问题,通常按照start排序,维护一个数组,每次取最后一个数作为比较的标准。
注意按照 start 或者 end 排序两种方式都可以求解,只是在不同情况下用其中之一代码编写更简洁。
本文总结了leetcode中重叠区间问题的题目,涉及到的题目如下:
- leetcode 56 合并区间
- leetcode 452 射气球
- leetcode 435 无重叠区间
- leetcode 763 划分字母区间
本题思路
回到本题,思路是,维护一个小根堆,里面存 end,当 start 大于最小的 end 时,说明前面的线段和当前的线段不可能同时被切,所以把前面的线段全部一刀切。
后来发现,不需要维护小根堆,只要用一个变量维护最小值就可以了。
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (o1, o2) -> (long) o1[0] - (long) o2[0] > 0 ? 1 : -1);
int count = 0;
long minEnd = Long.MAX_VALUE;
for (int[] pair : points) {
if (minEnd != Long.MAX_VALUE && pair[0] > minEnd) {
minEnd = Long.MAX_VALUE;
count++;
}
minEnd = Math.min(minEnd, pair[1]);
}
return count + 1; // 清算结尾
}
}
思路来源:左程云“最大线段重合问题”
另外,对于“求重叠最多的绳子条数”问题,见视频 15:49
package class04_07;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Code01_CoverMax {
public static int maxCover1(