day36打卡

day36打卡

435. 无重叠区间

我们把它看成一个预定会议问题,选择越早结束的会议就给后面空出来的时间越长,所以我们按照右边界排序(也就是按结束时间排序)。

按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了

class Solution {
    static bool cmp(vector<int>& a, vector<int>& b)
    {
        return a[1] < b[1];
    }
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        //先按右边界排序
        //sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b){
        //  return a[1] < b[1];
        //})
        sort(intervals.begin(), intervals.end(), cmp);
        //开始记录不重叠区间个数
        int count = 1;//把第一个当做不重叠区间
        int end = intervals[0][1];//记录右边界最小的区间
        for(int i = 1; i < intervals.size(); i++)
        {
            //比这个区间的右边界大,说明不重复
            if(intervals[i][0] >= end)
            {
                end = intervals[i][1];
                count++;
            }
        }
        return intervals.size() - count;
    }
};

763. 划分字母区间

题目要求同一字母最多出现在一个片段中,那么如何把同一个字母的都圈在同一个区间里呢?

在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

分为两步:

  • 统计所以字母出现的最后位置
  • 遍历寻找之前遍历过的所有字母的最远边界,如果找到字母最远出现位置下标和当前下标相等了,则找到了分割点

day36打卡_第1张图片

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;
        }
        // 遍历找到字母出现最后位置
        int begin = 0, end = 0;
        vector<int> ret;
        for(int i = 0; i < s.size(); i++)
        {
            // 找到字符出现的最远边界
            end = max(end, hash[s[i] - 'a']);
            if(i == end)
            {
                ret.push_back(end - begin + 1);
                begin = end + 1;
            }
        }
        return ret;
    }
};

56. 合并区间

和无重叠区间几乎一模一样,仅仅是因为合并区间修改为左边界排序。

day36打卡_第2张图片

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        //按左边界排序
        sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b){
            return a[0] < b[0];
        });
        //寻找不重叠区间和合并区间
        vector<vector<int>> ret;
        ret.push_back(intervals[0]);
        for(int i = 1; i < intervals.size(); i++)
        {
            //不重叠
            if(intervals[i][0] > ret.back()[1])
            {
                ret.push_back(intervals[i]);
            }
            else//重叠,合并
            {
                ret.back()[1] = max(ret.back()[1], intervals[i][1]);
            }
        }
        return ret;
    }
};

你可能感兴趣的:(代码,算法,leetcode)