4.更多练习题
2)力扣https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/解题思路:这题可以很直观地使用贪心算法,排序后的坐标,若有重叠,则保留重叠部分坐标,删除一对坐标,最后剩下的坐标数就是需要的弓箭数。
代码:
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
int n = points.size();
if(n<2) return n;
sort(points.begin(), points.end(),
[&](vector<int>& a, vector<int>& b){
if(a[0]==b[0]) return a[1]<b[1];
return a[0]<b[0];
}
);
int res = 0;
pair<int,int> pre;
pre.first = points[0][0];
pre.second = points[0][1];
for(auto p:points){
if(p[0]<=pre.second){
res++;
pre.first = max(pre.first, p[0]);
pre.second = min(pre.second, p[1]);
}else{
pre.first = p[0];
pre.second = p[1];
}
}
return n-res+1;
}
};
3)力扣https://leetcode.cn/problems/partition-labels/这道题其实还是前面提到的区间问题,将字母的起始坐标和结束坐标提取出来,成为一个区间,合并相交的区间。
代码:
class Solution {
public:
vector<int> partitionLabels(string s) {
set<char> st;
vector<vector<int>> v;
vector<int> res;
if(s.size()==0) return res;
for(int i=0;i<s.size();i++){
if(st.count(s[i])==0){
st.insert(s[i]);
int j = s.size()-1;
while(j>i && s[i]!=s[j]){
j--;
}
vector<int> t;
t.push_back(i);
t.push_back(j);
v.push_back(t);
}
}
pair<int,int> pre;
pre.first = v[0][0];
pre.second = v[0][1];
for(auto t : v){
if(t[0]<pre.second){
pre.second = max(pre.second, t[1]);
}else if(t[0]>pre.second){
res.push_back(pre.second-pre.first+1);
pre.first = t[0];
pre.second = t[1];
}
}
res.push_back(pre.second-pre.first+1);
return res;
}
};