代码随想录算法训练营第26天|452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间
LeetCode452
2025-02-26 17:57:49 星期三
题目描述:力扣452
文档讲解:代码随想录(programmercarl)452. 用最少数量的箭引爆气球
视频讲解:《代码随想录》算法视频公开课:贪心算法,判断重叠区间问题 | LeetCode:452.用最少数量的箭引爆气球
代码随想录视频内容简记
这个题的贪心策略的局部最优就是把直径重叠的气球尽量放到一起,全局最优就是可以用最少的箭射爆所有的气球。
梳理
-
首先需要对所有的气球的起始位置进行一个排序
-
之后按照气球的左边界和右边界的大小来判断是否重叠,如果没有重叠,
if (points[i][0] > points[i - 1][1]) results++,则需要增加一只箭来射爆所有的气球。如果有重叠,那么还需要判断下面的气球是否重叠,所以这里就一个很巧的操作,
比如上图的[2,8]和[7,12]是重叠的,那么下一步就该判断[2,8],[7,12],[10,16]三个气球是否重叠,这时候,只需要给[7,12]的右边界赋上[2,8]的右边界的值即可
注意
在两个气球重叠的时候,要注意赋值操作,不是points[i][1] = points[i - 1][1];,而是取重叠两个起球有边界的最小值points[i][1] = min(points[i - 1][1], points[i][1])
LeetCode测试
点击查看代码
class Solution {
private:
static bool cmp(vector<int> a, vector<int> b) {
return a[0] < b[0];
}
public:
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end(), cmp);
int result = 1;
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > points[i - 1][1]) result++;
else {
points[i][1] = min(points[i - 1][1], points[i][1]);
}
}
return result;
}
};
LeetCode435
题目描述:力扣435
文档讲解:代码随想录(programmercarl)435. 无重叠区间
视频讲解:《代码随想录》算法视频公开课:贪心算法,依然是判断重叠区间 | LeetCode:435.无重叠区间
记录
这个题和上一道简直一摸一样,直接就过了
LeetCode测试
点击查看代码
class Solution {
private:
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;
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
intervals[i][1] = min(intervals[i - 1][1], intervals[i][1]);
result++;
}
}
return result;
}
};
LeetCode763
题目描述:力扣763
文档讲解:代码随想录(programmercarl)763.划分字母区间
视频讲解:《代码随想录》算法视频公开课:贪心算法,寻找最远的出现位置! LeetCode:763.划分字母区间
代码随想录视频内容简记
这个题一开始的时候没有看出来哪里用到贪心了,其实是在题目中的这一句话
我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中
这道题贪心的局部最优就是对尽可能去找每一个字符出现的最远的位置,然后将其划分出来,那么全局最优就是可确保这样划分的片段,使同一字母最多出现在一个片段中,从而使划分的片段最多
梳理
-
这个题很巧妙和哈希法结合在了一起,首先统计每个字符出现的最远位置。这里需要先定义一个hash,之后用
hash[s[i] - 'a'] = i;来不断更新最远的距离 -
之后按照顺序遍历,这里的写法很巧,分别定义left和right,
right = max(hash[s[i] - 'a'], right) -
之后按照
result.push_back(right - left + 1)即可
LeetCode测试
点击查看代码
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;
}
int left = 0, right = 0;
vector<int> result;
for (int i = 0; i < s.size(); i++) {
right = max(right, hash[s[i] - 'a']);
if (right == i) {
result.push_back(right - left + 1);
left = i + 1;
}
}
return result;
}
};
浙公网安备 33010602011771号