给你很多形如 [start, end]
的闭区间,请你设计一个算法,算出这些区间中最多有几个互不相交的区间。
Non-overlapping Intervals
https://leetcode.com/problems/non-overlapping-intervals/description/
Given an array of intervals
intervals
whereintervals[i] = [starti, endi]
, return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
区间调度问题是让你计算若干区间中最多有几个互不相交的区间,这道题是区间调度问题的一个简单变体。
区间调度问题思路可以分为以下三步:
1、从区间集合
intvs
中选择一个区间x
,这个x
是在当前所有区间中结束最早的(end
最小)。2、把所有与
x
区间相交的区间从区间集合intvs
中删除。3、重复步骤 1 和 2,直到
intvs
为空为止。之前选出的那些x
就是最大不相交子集。
public int eraseOverlapIntervals(int[][] intervals) {
return intervals.length - intervalSchedule(intervals);
}
//区间调度问题 - 计算出不相交的区间个数
private static int intervalSchedule(int[][] intervals) {
//根据end进行升序排序
Arrays.sort(intervals,new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return a[1] - b[1];
}
});
int x_end = intervals[0][1];// 拿到最小end区间的最小end
int count = 1;//计算的是不相交的区间个数,即使全相交,那也有一个不相交,至少就一个
for(int i = 1; i < intervals.length; i++) {
if(x_end <= intervals[i][0]) {
count++;
x_end = intervals[i][1];
}
}
return count;
}
Minimum Number of Arrows to Burst Balloons
https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/
There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array
points
wherepoints[i] = [xstart, xend]
denotes a balloon whose horizontal diameter stretches betweenxstart
andxend
. You do not know the exact y-coordinates of the balloons.Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with
xstart
andxend
is burst by an arrow shot atx
ifxstart <= x <= xend
. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.Given the array
points
, return the minimum number of arrows that must be shot to burst all balloons.
public int findMinArrowShots(int[][] points) {
return intervalSchedule(points);
}
//贪心算法 - 区间调度问题 - 计算不相交区间的个数
private static int intervalSchedule(int[][] intervals) {
//根据end进行升序排序
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
if(a[1] < b[1]) {
return -1;
}else if(a[1] == b[1]) {
return 0;
}else {
return 1;
}
}
});
int count = 1; //被x_end覆盖到的区间有几个
int x_end = intervals[0][1];
for(int i = 1; i < intervals.length; i++) {
if(x_end < intervals[i][0]) {
count++;
x_end = intervals[i][1];
}
}
return count;
}