前言
本节内容为贪心算法中,关于重叠区间的问题,其实与贪心没多大关系,解题思路都比较靠技巧。
无重叠区间
题目详细:LeetCode.435
这道题和上一节的《LeetCode.452. 用最少数量的箭引爆气球》还蛮相似的,同样是对重叠区间进行判断和计算,思路都写在代码注释里了,详细的题解可查阅:《代码随想录》— 无重叠区间
Java解法:
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// 按左边界从小到大排序
Arrays.sort(intervals, (a, b) -> {
return a[0] - b[0];
});
// 非交叉区间的个数,移除多个重叠区间,最后至少存在一个
int count = 1;
for(int i = 1; i < intervals.length; i++){
if(intervals[i - 1][1] > intervals[i][0]){
// 上一个区间的右边界 > 当前区间的左边界,说明两个区间是相交的
// 保留一个两者之间最小的右边界,即相交的右边界
intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);
}else{
// 上一个区间相交的最大右边界 <= 当前区间的左边界
// 则说明当前区间与前面的区间都不相交,非交叉区间个数 + 1
count++;
}
}
// 最后利用(区间总数 - 非交叉区间的个数) = 移除区间的最小数量
return intervals.length - count;
}
}
划分字母区间
题目详细:LeetCode.763
根据前两个重叠区间问题的解题思路,在这道题中我直接尝试利用重叠区间来解题,解题思路如下:
- 遍历字符串,利用二维数组映射字符串中每个字符的区间,这里的区间下标我从1开始记录,主要是方便后面跳过空区间
- 接着,以区间的左边界对二维数组从小到大进行排序
- 因为有些字母在字符串中可能没有出现,所以需要跳过空区间,即跳过区间大小为
[0, 0]
的区间 - 定义一个变量 left,用于记录重叠区间起始的下标位置
- 循环比较当前区间的左边界和上一个区间的右边界
- 如果
上一个区间的右边界 > 当前区间的左边界
,则说明这两个区间是重叠的,让当前区间的右边界保留一个最大的右边界值 - 否则,说明两个区间不是重叠的,那么后续的区间中肯定不会出现重复的字母,所以产生一个划分点,注意划分后要更新变量 left
- 如果
- 当遍历到最后一个区间,最后的一个划分点刚好在数组尾部,但此时已结束循环,所以最后需要再补充添加最后一段重叠区间的划分长度。
Java解法(重叠区间):
class Solution {
public int[][] strToLetterRangeArr