代码随想录算法训练营Day 36 | LeetCode435. 无重叠区间、LeetCode763.划分字母区间、LeetCode56. 合并区间

LeetCode435. 无重叠区间

和上题引爆气球的逻辑非常像,只要想到左边界排序之后,更新右边界为最小值,则就可以轻松写出代码,如果按照右边界来排序,则就可以省去取最小值的逻辑。

代码如下:时间复杂度O(nlogn);空间复杂度O(n)(快排)

class Solution {
public:
    static bool cmp(vector<int> a,vector<int> b){
        if(a[0]==b[0]) return a[1]<b[1];
        return a[0]<b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end(),cmp);
        int result = 0;
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]<intervals[i-1][1]){
                result++;
                intervals[i][1] = min(intervals[i-1][1],intervals[i][1]);
            }
        }
        return result;
    }
};

LeetCode763.划分字母区间

本题首先记录每个字母最远出现的下标,然后不断遍历字符,判断是否到达最远下标,如果达到,则该下标之前的字符串可以作为一个字串保留。

本题的妙处:哈希表储存最远下标;max值不断维护最远下标。

代码如下:时间复杂度O(n);空间复杂度O(1)哈希表为固定大小。

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27]={0};
        vector<int> result;
        for(int i=0;i<s.size();i++){
            hash[s[i]-'a'] = i;
        }
        int end = hash[s[0]-'a'];
        int pre_end = 0;
        for(int i=0;i<s.size();i++){
            if(i==end){
                result.push_back(end+1-pre_end);
                pre_end = end+1;
                if(end==s.size()-1) break;
                end = hash[s[i+1]-'a'];
            }
            end = max(end,hash[s[i]-'a']);
        }
        return result;
    }
};

LeetCode56. 合并区间 

前面的题是在求交集,那么本题就是求并集,逻辑是一样的,如果重叠,更新右边界,不重叠,插入result数组中,左右边界都更新。代码如果简洁点可以直接利用result.back()[1]这种形式进行操作。

代码如下:时间复杂度O(nlogn);空间复杂度O(n)(快排)。

class Solution {
public:
    static bool cmp(vector<int> a,vector<int> b){
        if(a[0]==b[0]) return a[1]<b[1];
        return a[0]<b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end(),cmp);
        vector<vector<int>> result;
        vector<int> interval(2,0);
        interval[0] = intervals[0][0];
        interval[1] = intervals[0][1];
        for(int i=1;i<intervals.size();i++){
            if(intervals[i][0]>interval[1]){
                result.push_back(interval);
                interval[0] = intervals[i][0];
                interval[1] = intervals[i][1];
            }else if(intervals[i][0]<=interval[1]){
                interval[1] = max(intervals[i][1],interval[1]);
            }
        }
        result.push_back(interval);
        return result;
    }
};

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值