452. 用最少数量的箭引爆气球
局部最优:找到一支箭能贯穿最多的数组,那首先要让不同元素间有交集,首先排序,再看重合情况:1. [1, 3], [2, 4]中间有重合,重合区间是[2, 4];2. [1, 5], [2, 4]前者覆盖后者,重合区间时[2, 5];所以重合区间范围[points[i + 1][0], min(points[i][1], points[i+1][1])]。
class Solution {
public:
static bool cmp(vector<int>& a, vector<int>& b) {
return a[0] < b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
int sum = 1;
sort(points.begin(), points.end(), cmp);
for(int i = 0; i < points.size() - 1; ++i) {
if(points[i][1] < points[i+1][0]) {
sum++;
}else {
points[i+1][1] = min(points[i][1], points[i+1][1]);
}
}
return sum;
}
};
435. 无重叠区间
可以结合上一问,既然求的是多少箭能贯穿重合的数组;设不重叠数组的数目 = 所有数组数目 - 重合数组的数目。
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(),[](vector<int> v1,
vector<int> v2)
{
return v1[0] < v2[0];
});
int sum = 1;
for(int i = 0; i < intervals.size() - 1; ++i) {
//不重叠的情况
if(intervals[i][1] <= intervals[i+1][0]) {
sum++;
}else {//重叠则保留重合区间
intervals[i+1][1] = min(intervals[i+1][1], intervals[i][1]);
}
}
return intervals.size() - sum;
}
};
763.划分字母区间
局部最优:找到尽可能短的字符串片段;为了满足要求,首先记录每个字母最远的下标,然后该字母遍历到最远处后,考虑是否将其加入。该字符串尽量小但是满足要求。
class Solution {
public:
vector<int> partitionLabels(string s) {
//记录每个字母最远的下标
int a[26];
memset(a,0, sizeof(int));
for(int i = 0; i < s.size(); ++i) {
a[s[i] - 'a'] = i;
}
//找到最远边界
vector<int> res;
int right = 0;
int left = 0;
for(int i = 0; i < s.size(); ++i) {
right = max(right, a[s[i] - 'a']);
//找到s[i]的字母最远边界
if(right == i) {
res.push_back(right - left + 1);
left = right + 1;
}
}
return res;
}
};
173

被折叠的 条评论
为什么被折叠?



