435.无重叠区间
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//435.无重叠区间
static bool compareIntervals(const vector<int>& vnA, const vector<int>& vnB) {
return vnA[0] < vnB[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.size() == 0) {
return 0;
}
int nResult = 0;
//对数组进行排序
sort(intervals.begin(), intervals.end(), compareIntervals);
for (int i = 1; i < intervals.size(); i++) {
//当前区间左边界小于上个区间右边界
if (intervals[i][0] < intervals[i - 1][1]) {
//有重叠区间
nResult++;
//更新当前区间的右边界
intervals[i][1] = min(intervals[i - 1][1], intervals[i][1]);
}
}
return nResult;
}
2.本题小节
思考:本题和射气球很像,本质就是统计重叠区间的个数,对数组通过左区间进行排序,再进行重叠区间的统计。
基本思路:对数组进行排序,遍历,通过比较当前数组的左区间和上一个数组的有区间之间的大小关系来判断是否重叠,如如果重叠,则更新当前右区间,并记录次数,再进行进行下次遍历,遍历结束后,返回结果。
知识点:在compareIntervals中使用const 和 &,能够提高程序的性能,如果没用,提示超时。
763.划分字母区间
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//763.划分字母区间
vector<int> partitionLabels(string s) {
vector<int> vnResult;
int hash[26] = {0};
//取每个字母的最远下标
for (int i = 0; i < s.size(); i++) {
hash[s[i] - 'a'] = i;
}
int nStart = 0;
int nEnd = 0;
//划分区间
for (int i = 0; i < s.size(); i++) {
nEnd = max(nEnd, hash[s[i] - 'a']);
if (nEnd == i) {
//遍历到的位置为区间内所有字母的最大位置,开始划分
vnResult.push_back(nEnd - nStart + 1);
//更新nStart
nStart = nEnd + 1;
}
}
return vnResult;
}
2.本题小节
思考:本题的思路也是比较巧妙,要通过hash表记录每个元素所处的最大位置,然后一边遍历,一边更新最大位置,直到最大位置和遍历的位置相同,那么就开始划分区间。
本题小节:构建一个大小为26的hash表,通过遍历用来储存字符串中字母的最远位置,然后再次遍历字符串,模拟过程可以知道,每次更新当前字符的最远位置(通过max),直到最远位置和当前遍历位置相同时,划分出来的区间满足题目要求,这个时候通过end和start计算个数,再次更新start。
56.合并区间
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//56.合并区间
static bool compareIntervals(const vector<int>& vnA, const vector<int>& vnB) {
return vnA[0] < vnB[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> vvnResult;
//对数组进行排序
sort(intervals.begin(), intervals.end(), compareIntervals);
//插入第一个区间
vvnResult.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); i++) {
//当前区间的左边界小于等于上个区间的右边界,
//则合并区间
if (vvnResult.back()[1] >= intervals[i][0]) {
vvnResult.back()[1] = max(intervals[i][1], vvnResult.back()[1]);
}
else {
vvnResult.push_back(intervals[i]);
}
}
return vvnResult;
}
2.本题小节
思考:模拟合并过程,可以发现,在对数组进行左区间排序后,通过比较当前区间的左区间和上个区间的右区间来判断是否合并区间,如果需要合并区间,那么就合并。
基本思路:新建一个数组用于储存区间,将第一个区间放入到数组中,从第二个区间开始遍历,比较用于储存区间结果容器中的最后一个区间的右边界和当前区间左边界的关系,如果需要合并,则更新结果中的区间,不能合并,则将当前区间放进结果中。