赣榆区住房和城乡建设局网站,网站模板 古典,开网店需要什么手续和流程,中国机械工程LeetCode刷题day20——贪心 435. 无重叠区间763. 划分字母区间分析#xff1a; 56. 合并区间分析#xff1a; 435. 无重叠区间
给定一个区间的集合 intervals #xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量#xff0c;使剩余区间互不重叠 … LeetCode刷题day20——贪心 435. 无重叠区间763. 划分字母区间分析 56. 合并区间分析 435. 无重叠区间
给定一个区间的集合 intervals 其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量使剩余区间互不重叠 。
注意 只在一点上接触的区间是 不重叠的。例如 [1, 2] 和 [2, 3] 是不重叠的。
示例 1:
输入: intervals [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后剩下的区间没有重叠。示例 2:
输入: intervals [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。示例 3:
输入: intervals [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间因为它们已经是无重叠的了。提示:
1 intervals.length 105intervals[i].length 2-5 * 104 starti endi 5 * 104
//easy跟昨天的射气球一样的
class Solution {
public:int eraseOverlapIntervals(vectorvectorint intervals) {// 这道题完全就是昨天写的射气球的变体这里只需要求出非重叠区间的最大个数就能得知需要移除的区间个数int sum 0;sort(intervals.begin(), intervals.end(),[](vectorint a, vectorint b) { return a[1] b[1]; });int line INT_MIN;for (auto p : intervals) {if (p[0] line) {sum;line p[1];}}return intervals.size() - sum;}
};763. 划分字母区间
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段同一字母最多出现在一个片段中。
注意划分结果需要满足将所有划分结果按顺序连接得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
示例 1
输入s ababcbacadefegdehijhklij
输出[9,7,8]
解释
划分结果为 ababcbaca、defegde、hijhklij 。
每个字母最多出现在一个片段中。
像 ababcbacadefegde, hijhklij 这样的划分是错误的因为划分的片段数较少。 示例 2
输入s eccbbbbdec
输出[10]提示
1 s.length 500s 仅由小写英文字母组成
分析
构建字符的最后出现位置
使用一个 index 数组来记录每个字符在字符串中最后一次出现的位置。也就是说index[i] 存储的是字符 s[i] 在 s 中的最后一个位置。对于每个字符 s[i]通过第二层循环从 i1 到 n-1 遍历查找 s[i] 最后一次出现的索引更新 index[i]。
遍历并确定划分的点
接下来遍历字符串的每个字符维护一个 Max 变量记录到当前位置为止的字符的最远位置即 Max max(Max, index[i])。这个 Max 表示当前字符及其之前的所有字符可以在 Max 的范围内完全包含。如果当前索引 i 与 Max 相等说明从 start 到 i 这一段子串中的字符已经全部处理完可以作为一个独立的子串记录其长度并更新 start 为 i。
class Solution {
public:vectorint partitionLabels(string s) {//统计每个字符出现的最后位置然后从头开始遍历寻找最大的范围如果正遍历到最大范围就是切割点vectorint index(s.length(), 0);vectorint result;for (int i 0; i s.length(); i) {char c s[i];int tmp i;for (int j i 1; j s.length(); j) {if (c s[j])tmp j;}index[i] tmp;}int Max -1;int start -1;//这里注意题目求的是长度for (int i 0; i s.length(); i) {Max max(Max, index[i]);if (Max i) {result.push_back(i - start);start i;}}return result;}
};但是时间复杂度是O(N^2)因为在确定字母出现的最后位置时采用了两层循环。可以优化为O(N)。
class Solution {
public:vectorint partitionLabels(string s) {// 记录每个字符最后出现的位置vectorint lastIndex(26, -1); // 记录字符a到z的最后出现位置for (int i 0; i s.length(); i) {lastIndex[s[i] - a] i;}vectorint result;int start 0, end 0;for (int i 0; i s.length(); i) {// 更新end为当前字符的最后出现位置end max(end, lastIndex[s[i] - a]);// 如果当前索引i等于end说明可以分割if (i end) {result.push_back(i - start 1);start i 1; // 更新start为下一个分割点的起始位置}}return result;}
};
56. 合并区间
以数组 intervals 表示若干个区间的集合其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间并返回 一个不重叠的区间数组该数组需恰好覆盖输入中的所有区间 。
示例 1
输入intervals [[1,3],[2,6],[8,10],[15,18]]
输出[[1,6],[8,10],[15,18]]
解释区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2
输入intervals [[1,4],[4,5]]
输出[[1,5]]
解释区间 [1,4] 和 [4,5] 可被视为重叠区间。提示
1 intervals.length 104intervals[i].length 20 starti endi 104
分析
这题跟重叠区间射气球差不多。关键在于判断重叠之后要怎么处理。
class Solution {
public:vectorvectorint merge(vectorvectorint intervals) {sort(intervals.begin(), intervals.end(),[](vectorint x,vectorint y) {return x[0]y[0];});//按左边界排序vectorvectorint res;res.push_back(intervals[0]);for(int i0;iintervals.size();i) {if(res.back()[1]intervals[i][0]) {//重叠合并res.back()[1]max(res.back()[1],intervals[i][1]);}else//不重叠res.push_back(intervals[i]);}return res;}
};