2023.4.19 无重叠区间
这道题和引爆气球有点类似,我们需要找到重叠的区间,将其删去。先根据start进行排序,随后找出当前区间的左边起点在前一个区间的end之内的区间就是重叠区间,即我们需要删除的区间。
第一版代码
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
if(a[0] != b[0]){
return a[0]-b[0];
}
else{
return a[1]-b[1];
}
}
});
int count = 0;
for(int i = 1;i<intervals.length;i++){
if(intervals[i][0]<intervals[i-1][1]){//发生重叠
count++;
//由于需要移除区间,所以我们要更新右边界
intervals[i][1] = intervals[i-1][1];
}
}
return count;
}
}
错误原因,我们更新右边界时,不能直接选择上一个边界,因为有可能当前边界的右边界更小,我们需要选择更小的那个边界,这样才能获取的最少的删除区间数目。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
if(a[0] != b[0]){
return a[0]-b[0];
}
else{
return a[1]-b[1];
}
}
});
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][1],intervals[i][1]);
}
}
return count;
}
}
2023.4.19 划分字母区间
如何保证同一个字母只在一个片段中?使用lastIndexOf来判断。
我们使用双重循环,外层循环对整个字符串进行遍历,内层循环来更新片段的长度,
使用一个boolean数组来判断当前元素是否已经判断过了。
自己AC了。。
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> res = new ArrayList<>();
boolean[] isRead = new boolean[26];
int start = 0;
boolean index = true;
while(index){
int end = s.lastIndexOf(s.charAt(start));
isRead[s.charAt(start) - 'a'] = true;
for(int j = start + 1;j<end;j++){
if(isRead[s.charAt(j) - 'a']){//当前字符已经遍历过了
continue;
}else{//当前字符还没有遍历过
isRead[s.charAt(j) - 'a'] = true;
int newEnd = s.lastIndexOf(s.charAt(j));
end = Math.max(end,newEnd);//更新右边界。
}
}
//结束内层循环,返回长度。
res.add(end-start+1);
if(end == s.length()-1){
break;
}
//更新起始位置
start = end+1;
}
return res;
}
}
2023.4.19 合并区间
按照start其从小到大排序
然后判断是否重叠,如果重叠,更新边界,继续判断,如果不重叠,记录进结果中
public int compare(int[] a,int[] b){
return a[0]-b[0];
}
});
List<int[]> res = new ArrayList<>();
int start = intervals[0][0];
int end = intervals[0][1];
for(int i = 1;i<intervals.length;i++){
if(intervals[i][0] <= end){//区间重叠,
//更新右边界
end = Math.max(intervals[i][1],end);
}
else{//区间没有重叠,我们可以输出一个前一个的不重叠区间数组了。
int[] temp = {start,end};
res.add(temp);
//更新start和end
start = intervals[i][0];
end = intervals[i][1];
}
}
//注意,当i遍历到最后一个元素时,如果发生了重叠,此时会退出循环,不会进入else语句,所以当退出循环后我们还需要多进行一次add操作。
//最后一次add
int[] lastTemp = {start,end};
res.add(lastTemp);
return res.toArray(new int[res.size()][]);
}
}