455.分配饼干
思路:贪心算法;每次都考虑饥饿度最小的孩子,然后依次从最小的饼干出发,考虑是否可以满足;
代码:
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int cnt=0;
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int child=0,cookies=0;
while(child<g.size()&&cookies<s.size()){
if(s[cookies]>=g[child])++child;
++cookies;
}
return child;
}
};
135.分发糖果
题目描述:
思路:也是贪心算法的思路,先初始化,给每个人都只分发一个糖果;
然后从两个方向进行遍历循环,就可以满足:
(1)从左往右,若右边的分数高,右糖果=左+1;
(2)从右往左,若左比右高,且左糖果少,则左=右+1;
代码:
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> res(ratings.size());
for(int i=0;i<res.size();i++){
res[i]=1;
}
for(int j=1;j<ratings.size();j++){
if(ratings[j]>ratings[j-1])res[j]=res[j-1]+1;
}
for(int m=ratings.size()-2;m>=0;m--){
if(ratings[m]>ratings[m+1]&&res[m]<=res[m+1]){
res[m]=res[m+1]+1;
}
}
return accumulate(res.begin(), res.end(), 0);
}
};
435.Non-overlapping intervals
题目描述:
这道题最好的做法就是使用贪心算法,因为其实重要的是每个区间的右边界,思路就是优先保留右边界小且不相交的区间,先把区间按照结尾的大小进行升序排序,每次选择结尾最小且和前一个选择的区间不重叠的区间。
代码:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if(intervals.empty()){
return 0;
}
int n=intervals.size();
sort(intervals.begin(),intervals.end(),[](vector<int> a,vector<int> b){
return a[1]<b[1];
});
int total=0,prev=intervals[0][1];
for(int i=1;i<n;++i){
if(intervals[i][0]<prev){
++total;
}else{
prev=intervals[i][1];
}
}
return total;
}
};
605.种花问题
题目描述:
问题的重点在于,需要知道两颗已经种了的花之间可以种多少颗花:
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
int count = 0;
int m = flowerbed.size();
int prev = -1;
for (int i = 0; i < m; ++i) {
if (flowerbed[i] == 1) {
if (prev < 0) {
count += i / 2;
} else {
count += (i - prev - 2) / 2;
}
prev = i;
}
}
if (prev < 0) {
count += (m + 1) / 2;
} else {
count += (m - prev - 1) / 2;
}
return count >= n;
}
};
其中还要单独对一些情况进行分析,这道题不难,主要是要想清楚再开始写代码。
452.用最少数量的箭引爆气球
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if (points.size() == 0) return 0;
sort(points.begin(), points.end(), [](vector<int> a,vector<int> b){
return a[0]<b[0];
});
int result = 1; // points 不为空至少需要一支箭
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > points[i - 1][1]) { // 气球i和气球i-1不挨着,注意这里不是>=
result++; // 需要一支箭
}
else { // 气球i和气球i-1挨着
points[i][1] = min(points[i - 1][1], points[i][1]); // 更新重叠气球最小右边界
}
}
return result;
}
};