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

文章目录

  • 435. 无重叠区间
    • 思路
    • 代码
    • 总结
  • 763.划分字母区间
    • 思路
    • 代码
    • 总结
  • 56. 合并区间
    • 思路
    • 代码
    • 总结

435. 无重叠区间

思路

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

代码

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[0] < b[0];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size() == 0) return 0;

        sort(intervals.begin(), intervals.end(), cmp);

        int count = 0;
        int end = intervals[0][1];

        for(int i = 1; i < intervals.size(); i++) {
            if(intervals[i][0] >= end) {
                end = intervals[i][1];
            }
            else {
                end = min (end, intervals[i][1]);
                count++;
            }
        }
        return count;
    }
};

总结

763.划分字母区间

思路

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

代码

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 = i+1;
            }
        }

        return result;
    }
};

总结

  1. 另一种思路:统计字符串中所有字符的起始和结束位置,记录这些区间(实际上也就是435.无重叠区间题目里的输入),将区间按左边界从小到大排序,找到边界将区间划分成组,互不重叠。找到的边界就是答案。

56. 合并区间

思路

代码

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[0]<b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        // stack> st;
        // sort(intervals.begin(), intervals.end(),cmp);
        
        // st.push(intervals[0]);

        // for(int i = 1; i < intervals.size(); i++) {
        //     vector tmp = st.top();
        //     if(intervals[i][0] <= tmp[1]) {
        //         // 当前区间的start小于等于上一个区间的end
        //         // 当前区间和上一个区间重合
        //         int start = min(tmp[0], intervals[i][0]);
        //         int end = max(tmp[1], intervals[i][1]);
        //         intervals[i][0] = start;
        //         intervals[i][1] = end;
        //         st.pop();
        //         st.push(intervals[i]);
        //     }
        //     else {
        //         // 当前区间和上一个区间没有重合
        //         st.push(intervals[i]);
        //     }
        // }
        

        vector<vector<int>> result;
        if(intervals.size() == 0) return result;

        sort(intervals.begin(), intervals.end(),cmp);

        result.push_back(intervals[0]);

        for(int i = 1; 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;
    }
};

总结

  1. 思路不难
  2. 重叠区间的问题:找边界,但是按左边界排序和按右边界排序一定要确定好。
  3. 画图辅助

你可能感兴趣的:(代码随想录训练营,算法)