435. 无重叠区间
左边排序,右边裁剪为当前最小的
class Solution {
public:// 按照左边界排序static bool cmp(vector<int> a, vector<int> b) {return a[0] < b[0];}int eraseOverlapIntervals(vector<vector<int>>& intervals) {int res = 0;sort(intervals.begin(), intervals.end(), cmp);// i从1开始计数for (int i = 1; i<intervals.size(); i++) {// 仅当与上一条产生重叠时处理if (intervals[i][0] < intervals[i-1][1]) {res++;// 重叠时右边界统一切为最小值intervals[i][1] = min(intervals[i][1], intervals[i-1][1]);}}return res;}
};
763. 划分字母区间
自己写出来的题,虽然之前做过一遍了。
自己的写法虽然比较难看,但是也列出来了。
class Solution {
public:// 第二遍做,自己写出来的,耶耶耶vector<int> partitionLabels(string s) {unordered_map<char,int> umap;// 打印每个字符出现的最远记录for (int i = 0; i<s.size(); i++) {umap[s[i]] = i;}// 打印输出查看map记录for (auto [key,value]:umap){cout<<key<<" "<<value<<endl;}vector<int> res;// 当前字符串的最远角标int last = 0;// 当前字符串的起始角标int lastIndex = 0;for (int i = 0; i < s.size(); i++) {if (umap[s[i]] == i && last == i){res.push_back(i-lastIndex+1);lastIndex = i+1;last = i+1;}else {last = max(last, umap[s[i]]);}}return res;}
};
再给一个卡尔的写法
class Solution {
public:vector<int> partitionLabels(string S) {int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置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;}
};
56. 合并区间
重叠区域的题目大都要按左边界先排序。学了个lambda表达式。可以直接将一个区域放入结果集用res.back()[1]来更新右边界,这是一个好方法。
class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<vector<int>> res;if (intervals.size() == 0) return res;// 按左边界排序,lambda表达式sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){return a[0]<b[0];});res.push_back(intervals[0]);for (int i = 1; i<intervals.size(); i++) {// 如果左边界小于等于加入的尾部的右边界,更新尾部的右边界if (intervals[i][0] <= res.back()[1]) {res.back()[1] = max(res.back()[1],intervals[i][1]);}else {// 直接将下一段加入结果集res.push_back(intervals[i]);}}return res;}
};