455. 分发饼干
尽量满足多的孩子,就得尽可能的把小饼干发给胃口小的孩子,因此,可以对饼干和孩子排序,将小饼干发给小孩子,如果最小的饼干满足不了当前孩子,再将稍大一点的饼干给他试试,如果当前饼干满足要求,再尝试将更大一点的饼干给下一个孩子。
局部最优解:大饼干喂给大的或者小饼干喂给小的
全局最优解:尽可能满足最多的小孩
小饼干喂给小的
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int child = 0, cookie = 0; // 当前处理的孩子和饼干索引
while(child < g.size() && cookie < s.size()) {//饼干和孩子都没处理完
if (g[child] <= s[cookie]) child++; // 小饼干满足胃口,处理下一个孩子
cookie++; // 无论是否满足胃口,都要处理下一块饼干
}
return child;
}
};
大饼干喂给大的
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int child = 0, cookie = s.size() - 1; // 当前处理的孩子和饼干索引
for (int i = g.size() - 1; i >= 0; i--) {
if (cookie >= 0 && s[cookie] >= g[i]){
child++;
cookie--;
}
}
return child;
}
};
135. 分发糖果
贪心策略,保证每个孩子比左边右边比自己分低的孩子糖果多
局部最优:
- 每个孩子比它左边相邻的分低孩子糖多
- 每个孩子比它右边相邻的分低孩子糖多
全局最优:
- 每个孩子至少分配到 1 个糖果。
- 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
用两趟循环,一趟从左往右遍历,评分高的孩子都比左边孩子有更多的糖果;一趟从右往左遍历,评分高的孩子都比右边孩子有更多的糖果
class Solution {
public:
int candy(vector<int>& ratings) {
int n = ratings.size();
if (n < 2) return n;
vector<int> nums(n, 1); // 记录每个孩子的糖果数,初始都发1颗
// 从左往右遍历
for (int i = 1; i < n; i++) {
if (ratings[i] > ratings[i - 1]) { // 左边评分高于右边
nums[i] = nums[i - 1] + 1; //多一颗就行了,也算是贪心的策略
}
}
// 从右往左遍历, 只有从右往左遍历才能利用已经更新的结果(右边已经处理过)来更新左边的孩子
for (int i = n - 1; i > 0; i--) {
if (ratings[i] < ratings[i - 1]) { // 右边评分高于左边
nums[i - 1] = max(nums[i - 1], nums[i] + 1); // 如果本来就糖多,则不处理,否让TA糖比右边多一颗
}
}
return accumulate(nums.begin(), nums.end(), 0);
}
};