1. 无重叠区间
排序后,找重叠,找到则删掉右边界值大的(这样才能保证尽量不与下一个重叠)
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (o1, o2) ->{
return o1[0] - o2[0];
});
int count = 0;
for(int i = 1; i < intervals.length; i++){
if(intervals[i][0] < intervals[i-1][1]){
count++;// 删掉一个
// 删掉右边界大的区间,保留右边界小的,更新右边界
intervals[i][1] = Math.min(intervals[i][1], intervals[i-1][1]);
}
}
return count;
}
}
2. 划分字母区间
记录每个字母最远出现的位置
然后遍历字符串,动态记录一个区间内的所有字母最远出现的位置
到达记录的最大值,则找到一个划分区间
class Solution {
public List<Integer> partitionLabels(String s) {
int[] furthest = new int[26]; // 记录每一个字母出现的最远位置
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
furthest[c - 'a'] = i;
}
int max = 0;
int count = 0;
ArrayList<Integer> res = new ArrayList<>();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
// 区间内所有字母的最远出现位置
max = Math.max(max, furthest[c - 'a']);
count++;
if(i == max){
res.add(count);
count = 0;
}
}
return res;
}
}
3. 合并区间
找到重叠的区间后,合并,左边界取大的,右边界取小的
不重叠就将上一个区间添加到结果中
注意这种写法 要把最后一个区间单独加入一下
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
ArrayList<int[]> res = new ArrayList<>();
for(int i = 1; i < intervals.length; i++){
if(intervals[i][0] <= intervals[i-1][1]){ // 重叠
// 左边界取大的,右边界取小的
intervals[i][1] = Math.max(intervals[i][1], intervals[i-1][1]);
intervals[i][0] = Math.min(intervals[i][0], intervals[i-1][0]);
}else{
res.add(intervals[i-1]);
}
}
// 最后一个区间在循环中无法加入
res.add(intervals[intervals.length - 1]);
return res.toArray(new int[res.size()][]);
}
}