435.无重叠区间
代码随想录链接
题目
LeetCode-435.无重叠区间
给定区间的集合, 返回使得剩余区间不重叠而需要移除的最少区间数量
自己的思路
和昨天气球那题有点像,
气球的题目事实上求的是有几个能聚合在一起的重叠区间,
所以其实将返回值修改为区间总数减去聚合在一起的重叠区间的个数即可.
或者也可以先把区间按起始位置从小到大排列,
然后记录重叠的区间的个数.
题解
气球那题改的解法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { static bool cmp(const vector<int> &a, const vector<int> &b) { return a[0] < b[0]; } public: int eraseOverlapIntervals(vector<vector<int>>& intervals) { if (intervals.size() < 2) return 0; sort(intervals.begin(), intervals.end(), cmp); int count = 1; for (int i = 1; i < intervals.size(); i++) { if (intervals[i][0] < intervals[i - 1][1]) { intervals[i][1] = min(intervals[i - 1][1], intervals[i][1]); } else { count++; } } return intervals.size() - count; } };
|
记录重叠区间的个数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { static bool cmp(const vector<int> &a, const vector<int> &b) { return a[0] < b[0]; } public: int eraseOverlapIntervals(vector<vector<int>>& intervals) { if (intervals.size() < 2) 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 = min(end, intervals[i][1]); count++; } else { end = intervals[i][1]; } } return count; } };
|
763.划分字母区间
代码随想录链接
题目
LeetCode-763.划分字母区间
给定一个字符串, 将这个字符串划分为尽可能多的片段,
同一个字母最多出现在一个片段当中,
划分的结果按顺序连接起来依然是原字符串, 返回划分的片段的长度.
自己的思路
自己的想法是先将每个字母出现的起始和结束位置记录下来,
转化为合并重叠区间的问题. 也写出来了一个代码,
但是好像和题目的思想可能表述的不是很明白,
如果把只出现了一次的字母单独分段, 在一些情况下是对的, 一些情况下是错的,
所以还是把自己写的贴出来吧.
题解
自己写的(没有AC):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| class Solution { static bool cmp(const vector<int> &a, const vector<int> &b) { return a[0] < b[0]; } public: vector<int> partitionLabels(string s) { vector<int> result; vector<vector<int>> intervals(26, vector<int>(2, -1)); for (int i = 0; i < s.size(); i++) { int pos = s[i] - 'a'; if (intervals[pos][0] == -1) intervals[pos][0] = i; intervals[pos][1] = i; } for (int i = 0; i < intervals.size(); i++) { if (intervals[i][0] == -1) intervals.erase(intervals.begin() + i--); } sort(intervals.begin(), intervals.end(), cmp); for (int i = 0; i < intervals.size(); i++) { if (intervals[i][0] == intervals[i][1]) { if (i == intervals.size() - 1) intervals[i - 1][1] = intervals[i][0]; else intervals[i + 1][0] = intervals[i][1]; intervals.erase(intervals.begin() + i--); } } sort(intervals.begin(), intervals.end(), cmp); int start = 0, end = intervals[0][1]; for (int i = 1; i < intervals.size(); i++) { if (intervals[i][0] < intervals[i - 1][1]) end = max(intervals[i][1], end); else { result.push_back(end - start + 1); start = intervals[i][0]; end = intervals[i][1]; } } result.push_back(end - start + 1); return result; } };
|
卡哥的方法, 先统计每个字符出现的最后区间, 再重新遍历,
如果遇到了之前遍历过的所有字母的最远边界, 说明当前位置就是分割点.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { static bool cmp(const vector<int> &a, const vector<int> &b) { return a[0] < b[0]; } public: vector<int> partitionLabels(string s) { int lastPos[26] = {0}; for (int i = 0; i < s.size(); i++) lastPos[s[i] - 'a'] = i; vector<int> result; int left = 0, right = 0; for (int i = 0; i < s.size(); i++) { right = max(right, lastPos[s[i] - 'a']); if (i == right) { result.push_back(right - left + 1); left = i + 1; } } return result; } };
|
56.合并区间
代码随想录链接
题目
LeetCode-56.合并区间
对给定的区间中出现的重叠的区间进行合并, 区间是左闭右闭区间.
自己的思路
卡哥说这道题在今天的题中比较难, 我倒觉得还算简单的,
一次就A出来了.
同样还是先左边界排序, 右边界再判断是否重合及合并.
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { static bool cmp(const vector<int> &a, const vector<int> &b) { if (a[0] == b[0]) return a[1] < b[1]; return a[0] < b[0]; } public: vector<vector<int>> merge(vector<vector<int>>& intervals) { sort(intervals.begin(), intervals.end(), cmp); vector<vector<int>> result; vector<int> range; range.push_back(intervals[0][0]); range.push_back(intervals[0][1]); for (int i = 1; i < intervals.size(); i++) { if (intervals[i][0] <= range[1]) range[1] = max(range[1], intervals[i][1]); else { result.push_back(range); range[0] = intervals[i][0]; range[1] = intervals[i][1]; } } result.push_back(range); return result; } };
|