贪心算法
保证每次操作都是局部最优,使得最终结果也是全局最优的。
需要找到贪心的策略,使得每次的最优能保证全局最优。
通常需要排序。根据排序需求,自定义比较函数。
sort(a.begin(),a.end(),[](vector<int> a,vector<int> b){a[1]>b[1];});
技巧:有两种比较时,通常先满足一种,再考虑另一种,如果这两种可以分开,则可以局部最优到全局最优。
- 题目455,饼干分配问题
有一群有不同饥饿度的孩子和一堆不同大小的饼干,每个孩子只能吃最多一个饼干,且只有饼干的大小大于孩子的饥饿度时,这个孩子才能吃饱。求解最多有多少孩子可以吃饱。
思路:小孩饼干都升序排序,每个小孩吃满足他的最小的饼干
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
//都排序后,饼干按从小到大给从小到大的孩子分配
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int i = 0;//孩子胃口值从小到大排序后 的下标值
int cnt = 0;
for(int j=0; j<s.size(); j++){
if(s[j]>=g[i]){
cnt++; //满足情况分配给孩子,
i++; //继续看下一个孩子
if(i>=g.size()) //孩子分配完
return cnt;
}
}
return cnt;
}
};
- 题目135, 糖果分配问题
一群不同评分的孩子站成一排,如果一个孩子的评分比自己身旁的一个孩子要高,那么这个孩子就必须得到比身旁孩子更多的糖果;所有孩子至少要有一个糖果。求解最少需要多少个糖果。
思路:小孩都先发一个糖,从左到右遍历,若右边比左边孩子评分高则比左边多分一个,再由右往左遍历,如果左边比右边高,左边加1。
class Solution {
public:
int candy(vector<int>& ratings) {
int len = ratings.size();
int num=0;
vector<int> candy(len,1); //每个人先确保有一颗
for(int i=0; i<len-1; i++){
if(ratings[i+1]>ratings[i])
candy[i+1] = candy[i] + 1; //确保右边孩子比左边孩子评分高的 多拿一颗
}
for(int i=len-1; i>0; i--){
if(ratings[i-1]>ratings[i]&&candy[i-1]<=candy[i])
candy[i-1] = candy[i] + 1; //确保左边孩子比右边孩子评分高的 多拿一颗
num += candy[i];
}
num += candy[0];
return num;
}
};