【代码随想录训练营】【Day36】第八章|贪心算法|435. 无重叠区间|763.划分字母区间|56. 合并区间

前言

本节内容为贪心算法中,关于重叠区间的问题,其实与贪心没多大关系,解题思路都比较靠技巧。


无重叠区间

题目详细: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值