leetcode.452.用最少数量的箭射爆气球
class Solution {
public:
static bool cmp(const vector<int>& a,const vector<int>& b){//对Xend进行排序
return a[1]<b[1];
}
//这个题比较好贪,我们每次射只需要射Xend就可以了,然后用此次的Xend和之后几个气球的Xstart比较,如果这次射爆了好几个气球,那我们就不管这几个爆炸的气球了。
int findMinArrowShots(vector<vector<int>>& points) {
int count=0;
sort(points.begin(),points.end(),cmp);
for(int i=0;i<points.size();i++){
int l=i;
while(i+1<points.size()&&points[l][1]>=points[i+1][0]){
i++;//不管已经爆炸的气球
}
count++;
}
return count;
}
};
435.无重叠区间
这个题本来是一个挺标准的区间dp,但是直接裸dp超时了
class Solution {
public:
static bool cmp(const vector<int>& a,const vector<int>& b){//对Xend进行排序
return a[0]<b[0];
}
//按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了
int eraseOverlapIntervals(vector<vector<int>>& points) {
if(points.size()==0){
return 0;
}
int cmax=0;
sort(points.begin(),points.end(),cmp);
vector<int> f(points.size(),1);
for(int i=1;i<points.size();i++){
for(int j=0;j<i;j++){
if(points[j][1]<=points[i][0]){
f[i]=max(f[i],f[j]+1);
}
}
}
for(int i=0;i<points.size();i++){
if(cmax<f[i]){
cmax=f[i];
}
}
return points.size()-cmax;
}
};
贪心
class Solution {
public:
static bool cmp(const vector<int>& a,const vector<int>& b){//对Xend进行排序
return a[1]<b[1];
}
//按照右边界排序,从左向右记录非交叉区间的个数。
//最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了
int eraseOverlapIntervals(vector<vector<int>>& points) {
if(points.size()==0){
return 0;
}
int count=1;
sort(points.begin(),points.end(),cmp);
int end=points[0][1];
for(int i=1;i<points.size();i++){
if(end<=points[i][0]){
end=points[i][1];
count++;
}
}
return points.size()-count;
}
};
leetcode.763.划分字母区间
这道题我感觉极其抽象要多琢磨琢磨
每个字母最多出现在一个片段中
class Solution {
public:
vector<int> partitionLabels(string S) {
int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
hash[S[i] - 'a'] = i;
}
vector<int> result;
int left = 0;
int right = 0;
for (int i = 0; i < S.size(); i++) {
right = max(right, hash[S[i] - 'a']); // 找到字符出现的最远边界
if (i == right) {
result.push_back(right - left + 1);
left = i + 1;
}
}
return result;
}
};