代码随想录训练营Day36 贪心算法 part05● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

435. 无重叠区间

题目链接:435. 无重叠区间 - 力扣(LeetCode)

视频链接:贪心算法,依然是判断重叠区间 | LeetCode:435.无重叠区间

文章链接:代码随想录 (programmercarl.com)

这道题返回 需要移除区间的最小数量 ,那么我们只需要找到重叠区间的个数就可以了。

与Day35打气球那道题一样,这道题也需要先排序。

我这里使用的是从小到大排序。代码如下:

class Solution {
    static bool cmp(vector<int>& a,vector<int>& b)
    {
        return a[0]<b[0];
    }
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size()==0) return 0;
        sort(intervals.begin(),intervals.end(),cmp);
        int result=0;
        int end=intervals[0][1];
        for(int i=1;i<intervals.size();i++)
        {
            if(intervals[i][0]>=end) end=intervals[i][1];
            else
            {
                result++;//找到重叠的就结果加一
                end=min(end,intervals[i][1]);//更新最小右边界
            }
        }
        return result;
    }
};

763.划分字母区间

 题目链接:763. 划分字母区间 - 力扣(LeetCode)

视频链接:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间

文章链接:代码随想录 (programmercarl.com)

 这道题其实也是一道重叠问题。

同一字母只能出现在一个片段中,所以我们首先要找到每个字母在片段中出现的最终下标。然后通过循环遍历,更新自己的右边界。

其他字母的下标如果比前面一个小,就不变,如果大,就扩大右边界right。当我遍历到right时,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

代码如下:

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27]={0};
        for(int i=0;i<s.size();i++)
        {
            hash[s[i]-'a']=i;//找到每个字母出现的最终下标
        }
        vector<int> result;
        int left=0;
        int right=0;
        for(int i=0;i<s.size();i++)
        {
            right=max(right,hash[s[i]-'a']);//更新右边界
            if(i==right)
            {
                result.push_back(right-left+1);
                left=right+1;
            }
        }
        return result;
    }
};

56. 合并区间 

 题目链接:756. 合并区间 - 力扣(LeetCode)

视频链接:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间

文章链接:贪心算法,合并区间有细节!LeetCode:56.合并区间

 这道题也是重叠问题,合并区间也需要先找到重叠的区间,然后只要把右边界更新为原来右边界和重叠的右边界中大的那个就可以了。

代码如下:

class Solution {
    static bool cmp(vector<int>& a,vector<int>& b)//排序
    {
        return a[0]<b[0];
    }
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> result;
        if(intervals.size()==0) return result;
        sort(intervals.begin(),intervals.end(),cmp);//排序
        result.push_back(intervals[0]);//先把第一个放进去
        for(int i=0;i<intervals.size();i++)
        {
            if(result.back()[1]>=intervals[i][0])//判断是否重叠
            {
                result.back()[1]=max(result.back()[1],intervals[i][1]);//更新右边界
            }
            else{
                result.push_back(intervals[i]);//不重叠就把这个新的放进数组中
            }
        }
        return result;
    }
};

Day36打卡完成,耗时3小时,再接再厉吧。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值