排序后找重叠区间即可,有重叠区间就遍历到下一个气球,没有重叠区间就把箭的数量加一,然后到下一个气球
解法一:只看右边区间,因为已经根据左边区间排序,不用再考虑左边界的值,只需要考虑和变更右边界即可
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, Comparator.comparingInt(a -> a[0]));
int right = Integer.MAX_VALUE;
int count = 1;
for (int[] point : points) {
if (point[0] <= right || point[1] <= right) {
if (point[1] <= right) {
right = point[1];
}
continue;
} else {
count++;
right = point[1];
}
}
return count;
}
}
解法二:只考虑左边界是否在前一元素的右边界内
class Solution {
public int findMinArrowShots(int[][] points) {
if (points.length == 0) return 0;
Arrays.sort(points, (o1, o2) -> Integer.compare(o1[0], o2[0]));
int count = 1;
for (int i = 1; i < points.length; i++) {
if (points[i][0] > points[i - 1][1]) {
count++;
} else {
points[i][1] = Math.min(points[i][1], points[i - 1][1]);
}
}
return count;
}
}
解法三:同时考虑左右边界,有冗余的部分,其实在排序完已经过滤掉了。。。记录下原始想法,可优化成解法一或二
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (a, b) -> {
if (a[0] == b[0]) {
return b[1] - a[1];
}
return a[0] - b[0];
});
int left = Integer.MIN_VALUE;
int right = Integer.MAX_VALUE;
int count = 1;
for (int[] point : points) {
if ((point[0] >= left && point[0] <= right) || (point[1] <= right && point[1] >= left)) {
if (point[0] > left) {
left = point[0];
}
if (point[1] < right) {
right = point[1];
}
continue;
} else {
count++;
left = point[0];
right = point[1];
}
}
return count;
}
}