452. 用最少数量的箭引爆气球
class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b) {
if (a[1] == b[1]) return a[0] < b[0]; // 按照结束位置升序排列,若结束位置相同,按开始位置升序排列
return a[1] < b[1]; // 根据气球的结束位置排序
}
int findMinArrowShots(vector<vector<int>>& points) {
// 如果没有气球,返回 0
if (points.empty()) return 0;
// 对气球按照结束位置排序
sort(points.begin(), points.end(), cmp);
int ans = 1; // 至少需要一支箭
int k = points[0][1]; // 第一支箭的位置是第一个气球的结束位置
// 从第二个气球开始遍历
for (int i = 1; i < points.size(); i++) {
// 如果当前气球的起始位置大于上一支箭的结束位置,说明它们不重叠,需要新的一支箭
if (points[i][0] > k) {
ans++; // 新的箭
k = points[i][1]; // 更新箭的位置为当前气球的结束位置
}
}
return ans; // 返回最少箭矢数量
}
};
435. 无重叠区间
class Solution {
public:
// 比较函数:按照区间的结束时间进行升序排序
static bool cmp(const vector<int>& a, const vector<int>& b) {
return a[1] < b[1]; // 比较区间的结束时间,升序排列
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
// 对区间进行排序,排序规则是按照结束时间升序排列
sort(intervals.begin(), intervals.end(), cmp);
int ans = 0; // 用于记录需要删除的区间数
int k = intervals[0][1]; // 初始化当前区间的结束时间为第一个区间的结束时间
// 从第二个区间开始遍历
for (int i = 1; i < intervals.size(); i++) {
// 如果当前区间的起始时间小于前一个区间的结束时间,说明有重叠
if (k > intervals[i][0]) {
ans++; // 增加删除的区间数
} else {
// 如果没有重叠,更新当前区间的结束时间
k = intervals[i][1];
}
}
return ans; // 返回删除的区间数
}
};
763.划分字母区间
class Solution {
public:
// 该比较函数记录字符在字符串中最后一次出现的索引
vector<int> partitionLabels(string s) {
const int N = 1e5; // 假设足够大的数组大小
int a[N]; // 用于记录每个字符在字符串中的最后一次出现的位置
memset(a, 0, sizeof(a)); // 初始化数组为 0
// 遍历字符串,记录每个字符的最后出现位置
for (int i = 0; i < s.size(); i++) {
a[s[i]] = i; // 存储字符s[i]最后出现的位置
}
int max1 = a[s[0]]; // 初始最大右边界为第一个字符的最后位置
vector<int> v; // 存储最终的分割区间的长度
int pre = -1; // 记录上一个分割点的位置
// 遍历字符串,根据最大右边界划分子字符串
for (int i = 0; i < s.size(); i++) {
max1 = max(max1, a[s[i]]); // 更新当前子字符串的最大右边界
// 如果当前索引 i 达到最大右边界,说明可以确定一个子字符串
if (i == max1) {
v.push_back(i - pre); // 计算当前子字符串的长度并加入结果
max1 = 0; // 重置最大右边界
pre = i; // 更新分割点为当前的索引
}
}
return v; // 返回所有子字符串的长度
}
};