435. 跟昨天的最后一题差不多,今天静下心来看看也不是很难。需要自己去画个图先想下思路。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) return 0;
//按照左边界进行排序
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
int count=0;
int end = intervals[0][1]; // 初始化第一个区间的右边界
//从1开始遍历,刚开始才能比较i-1。从第二个区间开始遍历
for(int i=1; i<intervals.length; i++){
if(end > intervals[i][0]){
count++;
//更新右边界
end = Math.min(end, intervals[i][1]);
}else{
end = intervals[i][1];
}
}
return count;
}
}
763. 当我看到这个题目直接看不懂的时候就知道应该直接看题解了。看完之后整体还不算难,第一步用数组来记录每个字符出现的最远位置真的是太巧妙了,值得学习!
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> res = new LinkedList<>();
int[] hash = new int[26];
//记录每个字母出现的最远的位置!
for(int i=0; i<s.length(); i++){
hash[s.charAt(i) - 'a'] = i;
}
int left=0;
int right=0;
for(int i=0; i<s.length(); i++){
//分割线
right = Math.max(right, hash[s.charAt(i) - 'a']);
if(i == right){
res.add(right - left + 1); // 修正长度计算
left = right + 1; // 更新left为right的下一个位置
}
}
return res;
}
}
56. 有点难度,需要考虑的有点多,但是和今天的第一题其实也不是差很多。在重叠的时候合并区间而不是简单的计算有几个重叠区间。
贪心算法,合并区间有细节!LeetCode:56.合并区间_哔哩哔哩_bilibili
class Solution {
public int[][] merge(int[][] intervals) {
List<int[]> res = new LinkedList<>();
//按照左边界排序
Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
//initial start 是最小左边界
int start = intervals[0][0];
int rightmostRightBound = intervals[0][1];
for (int i = 1; i < intervals.length; i++) {
//如果左边界大于最大右边界
if (intervals[i][0] > rightmostRightBound) {
//加入区间 并且更新start
// 这里add不用intervals[i][1]而是rightmostRightBound,是因为考虑是否存在更早前的区间已经有一个更远的结束点
res.add(new int[]{start, rightmostRightBound});
start = intervals[i][0];
rightmostRightBound = intervals[i][1];
} else {
//更新最大右边界
// intervals[i]可能与前一个区间重叠,或者完全位于前一个区间内
rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);
}
}
// 确保最后一个正在处理的区间被正确加入到结果列表中
res.add(new int[]{start, rightmostRightBound});
return res.toArray(new int[res.size()][]);
}
}