代码随想录第三十六天|无重叠区间、划分字母区间、合并区间

Leetcode 435. 无重叠区间

题目链接: 无重叠区间
自己的思路:虽然相似,但是想不出来!!!

正确思路:其实和射气球一个思路,但是没有想通!主要是当当前区间的左边界大于前一个区间的右边界的时候,说明有重叠的,需要去除一个重叠区间,result需要加1,然后需要更新当前区间的右边界,因为我们要判断后面的区间是否和这两个区间也重叠,如果重叠result加1,不重叠则不需要改变!!!

代码:

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        //记录重叠区间的个数
        int result = 0;
        //按左边界排序
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        //如果当前区间的左边界小于前一个区间的右边界,说明重叠
        for (int i=1;i<intervals.length;i++){
            if (intervals[i][0]<intervals[i-1][1]){
                result++;
                //更新当前区间的右边界,以便判断后续的区间是否和这两个也重叠
                intervals[i][1]=Math.min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return result;
    }
}

Leetcode 763. 划分字母区间

题目链接: 划分字母区间
自己的思路:想不到,想不到!!!!好难!!!!

正确思路:注意题目的特点,一种字符串不能同时出现在两个区间里,所以我们在遍历字符串的时候,一定要知道至今出现的字符的最远距离,知道了最远距离我们就知道了什么时候我们的res集合收集结果!!!!

代码:

class Solution {
    public List<Integer> partitionLabels(String s) {
        //类似hash的思想,记录某个字符的最远位置
        int[] hash = new int[26];
        List<Integer> res = new ArrayList<>();
        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是至今出现的元素的最远距离
            right = Math.max(right,hash[s.charAt(i)-'a']);
            //如果当前的索引等于最大值,说明后面没有再出现和之前相同的元素了
            if (i==right){
                res.add(right-left+1);
                //更新左区间
                left = right+1;
            } 
        }
        return res;
    }
}

Leetcode 56. 合并区间

题目链接: 合并区间
自己的思路:没想到,区间的还是不熟!!!

正确思路:其实比上两道区间的题简单,就是没想到!还是老规矩,先将区间按左边界进行排序,排序好之后,我们先把第一个区间加入到res数组中,这样方便我们后续对他更改,遍历二维数组,当当前的区间的左边界小于等于上一个区间(我们res数组的最后一个元素)的右边界的时候,说明重合了,我们选择更新上一个区间,上一个区间的左边界不动,只更新右边界,右边界变为这个区间的右边界和上一个区间(res数组的最后一个元素)的右边界的最大值,否则我们说明和上一个区间(我们res数组的最后一个元素)不重合,直接把当前区间加入到res数组即可!!!

代码:

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length==0) return null;
        List<int[]> res = new ArrayList<>();
        //先按左边界进行排序
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        //加入第一个区间
        res.add(new int[]{intervals[0][0],intervals[0][1]});
        for (int i =1;i<intervals.length;i++){
            //当前区间的左边界小于等于上一个区间的右边界
            if (intervals[i][0]<=res.get(res.size()-1)[1]){
                //说明重叠,更新上一个区间右边界
                res.get(res.size()-1)[1] = Math.max(intervals[i][1],res.get(res.size()-1)[1]);
            }else{
                //不重叠,就把当前区间加进去
                res.add(new int[]{intervals[i][0],intervals[i][1]});
            }
        }
        return res.toArray(new int[res.size()][]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值