重点:维护一个最右区间长度。
LeetCode452. 用最少数量的箭引爆气球
public int findMinArrowShots(int[][] points) {
if(points.length==0) return 0;
Arrays.sort(points,new Comparator<int[]>() {
public int compare(int[] point1,int[]point2) {
return Integer.compare(point1[0], point2[0]);
}
});
int sum=1;
//只用判断相邻的元素,每次更新此位置的最小右边界即可
for(int i=1;i<points.length;i++) {
if(points[i][0]>points[i-1][1]) {
sum++;
}else {
points[i][1]=Math.min(points[i][1], points[i-1][1]);
}
}
return sum;
}
LeetCode435. 无重叠区间
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length==0) return 0;
Arrays.sort(intervals,new Comparator<int[]>() {
public int compare(int[] point1,int[]point2) {
return Integer.compare(point1[0], point2[0]);
}
});
int sum=1;
//逆向思维,只用求不交叉的个数就行了
for(int i=1;i<intervals.length;i++) {
if(intervals[i][0]>=intervals[i-1][1]) {
sum++;
}else {
intervals[i][1]=Math.min(intervals[i][1], intervals[i-1][1]);
}
}
return intervals.length-sum;
}
LeetCode763.划分字母区间
public List<Integer> partitionLabels(String s) {
List<Integer> list = new LinkedList<>();
int[] edge = new int[26];
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
edge[chars[i] - 'a'] = i;
}
//如果目前所有字母的最远边界都在里面(每次更新最大边界就好了)维护一个最大边界
int max=-1,start=0;
for(int i = 0; i < chars.length; i++) {
max=Math.max(max,edge[chars[i]-'a']);
if(max==i) {
list.add(i-start+1);
start=i+1;
}
}
return list;
}