代码随想录算法训练营第36天|435. 无重叠区间,763. 划分字母区间,56. 合并区间

435. 无重叠区间

力扣题目链接

思路

  • 这道题似乎是用最少数量的箭引爆气球的反面
  • 需要移除的区间数=总区间数-不重叠的区间数
  • 因此,本题的关键是求出不重叠的区间数(类似射气球,不能一起射的气球就是不重叠的)

步骤:

  • 按右边界从小到大排序
  • 如果重叠区间的右边界<=当前新进入区间的左边界,则不重叠,不重叠区间数加一
  • 返回总区间数-不重叠的区间数

为什么按右边界排序:

  • 我们判断是否重叠,是通过比较下一个区间的左边界和当前重叠区间最小右边界。
  • 因为右边界越小越好,只要右边界越小,留给下一个区间的空间就越大,就能求出更多不重叠的区间
  • 下面区间中1与2重叠,假如3的左边界与1的右边界比较,会认为3与1重叠,这样就会导致1与2与3重叠,判断出不重叠区间只有1个;假如假如3的左边界与2的右边界比较,会认为3与2不重叠,那么重叠区间有两个。(几个区间重叠在一起得看它最小的右边界在哪才能判断是否与下一个重叠,这样保证原来重叠的都可以和新进入的区间重叠上)

代码随想录算法训练营第36天|435. 无重叠区间,763. 划分字母区间,56. 合并区间_第1张图片

代码

class Solution {
public:
    static bool cmp(const vector& a,const vector& b){
        return a[1]>& intervals) {
        sort(intervals.begin(),intervals.end(),cmp);
        int res=1; 
        int cur=intervals[0][1]; // 右边界
        for(int i=1;i
  • 时间复杂度O(nlogn)
  • 空间复杂度O(logn)

763. 划分字母区间

力扣题目链接

思路

我的方法

  • i从左向右遍历
  • j从右向左遍历,寻找数组中最后一次出现s[i]的位置,划分[i,j]为一个字符串片段
  • cur记录当前划分的字符串片段的右边界,pre记录上一个字符串的右边界
  • 当i!=cur时,如果j>cur,说明[pre+1,j]比[pre+1,cur]长,更新cur=j
  • 当i==cur时,说明当前字符串片段已遍历完成,记录当前字符串片段的长度,寻找下一个字符串片段

代码随想录

  • 在寻找之前遍历过的所有字母的最远边界上使用了哈希法

代码

我的方法

class Solution {
public:
    /*
     * i从左向右遍历
     * j从右向左遍历,寻找数组中最后一次出现s[i]的位置,划分[i,j]为一个字符串片段
     * cur记录当前划分的字符串片段的右边界,pre记录上一个字符串的右边界
     * 当i!=cur时,如果j>cur,说明[pre+1,j]比[pre+1,cur]长,更新cur=j
     * 当i==cur时,说明当前字符串片段已遍历完成,记录当前字符串片段的长度,寻找下一个字符串片段
    */
    vector partitionLabels(string s) {
        int cur=0; // 当前字符串片段的右边界
        int pre=-1; // 上一个字符串片段的右边界
        vector res;
        for(int i=0;i=0;j--){
                if(s[i]==s[j]&&cur
  • 时间复杂度O(n^2)
  • 空间复杂度O(1)

代码随想录

class Solution {
public:
    vector partitionLabels(string s) {
        int hash[27] = {0};
        for (int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a'] = i; // 统计每个字符最后出现的位置
        }
        int left = 0; // 左边界
        int right = 0; // 右边界
        vector res;
        for(int i = 0; i < s.size(); i++) {
            right = max(right, hash[s[i] - 'a']);
            if(i == right) {
                res.push_back(right - left + 1);
                left = right + 1;
            }
        }
        return res;
    }
};
  • 时间复杂度O(n)
  • 空间复杂度O(c)

56. 合并区间

力扣题目链接

思路

我的方法

  • 关键:只要有重叠就合并区间
  • 区间按左边界从小到大排序
  • 当下一个区间的左边界<=上一个区间的右边界时,说明区间可以合并,更新合并后区间的右边界(取更大的那个边界作为右边界)
  • 否则,将上一个区间的左右边界加入结果集
  • 遍历完成后,加入最后一个区间到结果集

代码随想录

  • 区间按左边界从小到大排序
  • 将第一个区间加入结果集
  • 当下一个区间的左边界<=结果集中最后一个区间的右边界时,说明区间可以合并,更新结果集最后一个区间的右边界
  • 否则,将下一个区间加入结果集

代码

我的方法

class Solution {
public:
    static bool cmp(const vector& a, const vector& b){
        return a[0] < b[0];
    }
    vector> merge(vector>& intervals) {
        sort(intervals.begin(), intervals.end(), cmp); // 区间按左边界从小到大排序
        int left = intervals[0][0]; // 左边界
        int right = intervals[0][1]; // 右边界
        vector> res;
        for(int i = 1; i < intervals.size(); i++) {
            if(right < intervals[i][0]) { //到达不同区间的分割点,将上一个区间加入结果集
                vector temp;
                temp.push_back(left);
                temp.push_back(right);
                res.push_back(temp);
                left = intervals[i][0];
                right = intervals[i][1];
            }
            else { // 合并区间
                right=max(right,intervals[i][1]);
            } 
        }
        //加入最后一个区间到结果集
        vector temp;
        temp.push_back(left);
        temp.push_back(right);
        res.push_back(temp);
        return res;
    }
};
  • 时间复杂度O(nlogn)
  • 空间复杂度O(1ogn)

代码随想录

class Solution {
public:
    static bool cmp(const vector& a, const vector& b) {
        return a[0] < b[0];
    }
    vector> merge(vector>& intervals) {
        sort(intervals.begin(), intervals.end(), cmp); // 按左边界从小到大排序
        vector> res;
        res.push_back(intervals[0]); // 将第一个区间放入结果集
        for(int i = 1; i < intervals.size(); i++) {
            if(res.back()[1] < intervals[i][0]) // 到达分割点
                res.push_back(intervals[i]); // 将新区间放入结果集
            else // 合并区间
                res.back()[1] = max(res.back()[1], intervals[i][1]); //更新右边界
        }
        return res;
    }
};
  • 时间复杂度O(nlogn)
  • 空间复杂度O(1ogn)

你可能感兴趣的:(代码随想录刷题,算法,leetcode,贪心算法)