435.无重叠区间
题目要求移除区间的数量最小,是剩余区间不重复
思路:
将intervals按照第一个值的升序排序。然后跟昨天气球的思路一样
第一次错误:
重写的Comparator乜有满足自反性,传递性,对称性
自反性:当 两个相同的元素相比时,compare必须返回0,也就是compare(o1, o1) = 0;
反对称性:如果compare(o1,o2) = 1,则compare(o2, o1)必须返回符号相反的值也就是 -1;
传递性:如果 a>b, b>c, 则 a必然大于c。也就是compare(a,b)>0, compare(b,c)>0, 则compare(a,c)>0
解决方式:
Arrays.sort(intervals,(a,b)->{
if (a[0] < b[0]){
return -1;
}
return 1;
});
修改为
Arrays.sort(intervals,(a,b)->{
return Integer.compare(a[0],b[0]);
});
public class LeetCode435 {
public int eraseOverlapIntervals(int[][] intervals) {
//记录删除的区间数目
int count = 0;
//对intervals按照升序排序
Arrays.sort(intervals,(a,b)->{
return Integer.compare(a[0],b[0]);
});
for(int i = 1;i < intervals.length;i++){
//如果出现了重叠的区间,则将后面的那个删掉
if (intervals[i][0] >= intervals[i-1][0] && intervals[i][0] < intervals[i-1][1] ){
intervals[i][1] = Math.min(intervals[i-1][1],intervals[i][1]);
count++;
}
}
return count;
}
763.划分字母区间
读了好几遍题,才了解到“同一字母最多出现在一个片段中”并不是指具体的哪一个字母“
题目要求划分后仍然顺序链接后仍然是原来的字符串,所以不能排序之类的
没思路,看题解:
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
可以分为如下两步:
- 统计每一个字符最后出现的位置
- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
主要是这个第二步,你遍历字符串的时候,就相当于一直在更新当前区间内所有字母可以出现的最远位置,那一旦当前的索引与最远位置相等了,那么就表明,当前这个区间已经找完了。由于题目要求是尽可能多的分隔字符串,那我们要保证同一区段内尽可能少的有不同字母。
第一次错误:
使用last记录上一次分割位置的时候,last要初始化为 -1.
public List<Integer> partitionLabels(String s) {
List<Integer> result = new ArrayList<>();
int[] end = new int[26];
//遍历字符串,记录每个字符在字符串中结束的位置。
for ( int i = 0 ; i < s.length();i++){
end[s.charAt(i) - 'a'] = i;
}
//记录当前区间内字母最远出现的距离
int max = -1;
//记录上一区间的最远距离(即上一分割点的位置)
int last = 0;
for (int i = 0; i<s.length(); i++){
max = Math.max(end[s.charAt(i) - 'a'],max);
if (i == max){
result.add(max-last);
last = i;
}
}
return result;
}
56. 合并区间
这个与今天的重叠区间题类似。不过本题并不是要取最小值,而是要不断的扩展范围。
第一次错误:
最后一个值没有加进来,所以在for循环结束后,把最后一个值也加到结果里面。
public int[][] merge(int[][] intervals) {
List<int[]> tmp = new ArrayList<>();
//将intervals安装start升序进行排序
Arrays.sort(intervals, (a,b)->{
return Integer.compare(a[0],b[0]);
});
for (int i = 1; i < intervals.length;i++){
//如果第二个区间与第一个区间有重叠的地方
if (intervals[i][0] <= intervals[i-1][1]&& intervals[i][0] >= intervals[i-1][0]){
intervals[i][0] = intervals[i-1][0];
intervals[i][1] = Math.max(intervals[i][1],intervals[i-1][1]);
}else {
tmp.add(intervals[i-1]);
}
}
//要把最后一个结果也加上。
tmp.add(intervals[intervals.length -1]);
return tmp.toArray(new int[tmp.size()][]);
}