435. 无重叠区间
题目链接:435. 无重叠区间 - 力扣(LeetCode)
视频链接:贪心算法,依然是判断重叠区间 | LeetCode:435.无重叠区间
文章链接:代码随想录 (programmercarl.com)
这道题返回 需要移除区间的最小数量 ,那么我们只需要找到重叠区间的个数就可以了。
与Day35打气球那道题一样,这道题也需要先排序。
我这里使用的是从小到大排序。代码如下:
class Solution {
static bool cmp(vector<int>& a,vector<int>& b)
{
return a[0]<b[0];
}
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if(intervals.size()==0) return 0;
sort(intervals.begin(),intervals.end(),cmp);
int result=0;
int end=intervals[0][1];
for(int i=1;i<intervals.size();i++)
{
if(intervals[i][0]>=end) end=intervals[i][1];
else
{
result++;//找到重叠的就结果加一
end=min(end,intervals[i][1]);//更新最小右边界
}
}
return result;
}
};
763.划分字母区间
题目链接:763. 划分字母区间 - 力扣(LeetCode)
视频链接:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间
文章链接:代码随想录 (programmercarl.com)
这道题其实也是一道重叠问题。
同一字母只能出现在一个片段中,所以我们首先要找到每个字母在片段中出现的最终下标。然后通过循环遍历,更新自己的右边界。
其他字母的下标如果比前面一个小,就不变,如果大,就扩大右边界right。当我遍历到right时,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
代码如下:
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=right+1;
}
}
return result;
}
};
56. 合并区间
视频链接:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间
文章链接:贪心算法,合并区间有细节!LeetCode:56.合并区间
这道题也是重叠问题,合并区间也需要先找到重叠的区间,然后只要把右边界更新为原来右边界和重叠的右边界中大的那个就可以了。
代码如下:
class Solution {
static bool cmp(vector<int>& a,vector<int>& b)//排序
{
return a[0]<b[0];
}
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> result;
if(intervals.size()==0) return result;
sort(intervals.begin(),intervals.end(),cmp);//排序
result.push_back(intervals[0]);//先把第一个放进去
for(int i=0;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;
}
};
Day36打卡完成,耗时3小时,再接再厉吧。