代码随想录——贪心13.分发糖果
思路
一开始受到“摆动序列”的影响画图,有想过从左往右遍历,if当前孩子大于左孩子就比左孩子大1,else if大于右孩子就比右孩子大1
这样能保证“相邻两个孩子评分更高的孩子会获得更多的糖果。”但是不能保证每个人至少有1个糖果。
于是又想从右向左遍历,对于糖果数小于1个的做处理,此时发现很难通过一次遍历处理好。于是只能看答案了。
答案直接指出问题:“这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼。”
正确方法:
- 从左向右遍历,只关注右边评分大于左边的情况
- 从右向左遍历,只关注左边评分大于右边的情况
但是为保证同时大于两边,取当前糖果数和第一次遍历得到的糖果数的最大值
因此通过两次局部最优,得到了全局最优
代码
class Solution {
public:
int candy(vector<int>& ratings) {
int sum=0;
vector<int> candy(ratings.size(),1);
for(int i=1;i<ratings.size();i++){
if(ratings[i] > ratings[i-1]){//当前孩子分数比左孩子大
candy[i] = candy[i-1] + 1;
}
}
for(int i=ratings.size()-2;i>-1;i--){
if(ratings[i] > ratings[i+1]){//当前孩子比右边大
candy[i] = max(candy[i+1]+1,candy[i]);//要同时满足比两边大,取max
}
}
for(int a:candy)sum+=a;
return sum;
}
};