今天的三道题目,都算是 重叠区间 问题,大家可以好好感受一下。 都属于那种看起来好复杂,但一看贪心解法,惊呼:这么巧妙!还是属于那种,做过了也就会了,没做过就很难想出来。
不过大家把如下三题做了之后, 重叠区间 基本上差不多了
435. 无重叠区间
代码随想录
和射气球那个题比较像。
Python:
class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if len(intervals)==1: return 0intervals.sort()ans = 0for i in range(1, len(intervals)):if intervals[i][0] < intervals[i-1][1]:intervals[i][1] = min(intervals[i-1][1], intervals[i][1])ans += 1return ans
C++:
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()==1) return 0;sort(intervals.begin(), intervals.end(), cmp);int result = 0;for (int i=1; i<intervals.size(); i++) {if (intervals[i][0] < intervals[i-1][1]) {intervals[i][1] = min(intervals[i][1], intervals[i-1][1]);result++;}}return result;}
};
763.划分字母区间
代码随想录
Python暴力法:
分情况讨论,需要多建一个当前字母集合。
class Solution:def partitionLabels(self, s: str) -> List[int]:occ_dict = {}for i,e in enumerate(s):occ_dict[e] = iresult = []cur_ele_set = set()cur_start = -1for i,e in enumerate(s):if occ_dict[e] > i:cur_ele_set.add(e)elif e in cur_ele_set:cur_ele_set.remove(e)if len(cur_ele_set)==0:result.append(i-cur_start)cur_start = ireturn result
C++贪心:
一是学一下用hash来表示这里的occ_map,会比dictionary更节省空间, 二是卡哥这里用max贪心的思想来更新右节点,用right==i来判断,很巧妙。python版本比较直接。
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 = -1;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);left = i;}}return result;}
};
56. 合并区间
本题相对来说就比较难了。
代码随想录
Python:
先按左端点排序,然后按是否overlap分类讨论,看是否更新区间或者结果。
class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:n = len(intervals)if n==1: return intervalsintervals.sort()result = []left, right = intervals[0]for i in range(1, n):if intervals[i][0] > right:result.append([left, right])left, right = intervals[i]else:right = max(right, intervals[i][1])result.append([left, right]) return result
C++:
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) {if (intervals.size()==1) return intervals;sort(intervals.begin(), intervals.end(), cmp);vector<vector<int>> result;int left = intervals[0][0];int right = intervals[0][1];for (int i=1; i<intervals.size(); i++) {if (intervals[i][0]>right) {result.push_back(vector<int> {left, right});left = intervals[i][0];right = intervals[i][1];} else {right = max(right, intervals[i][1]);}}result.push_back(vector<int> {left, right});return result;}
};