代码随想录——贪心13.分发糖果

image
image

思路

一开始受到“摆动序列”的影响画图,有想过从左往右遍历,if当前孩子大于左孩子就比左孩子大1,else if大于右孩子就比右孩子大1
这样能保证“相邻两个孩子评分更高的孩子会获得更多的糖果。”但是不能保证每个人至少有1个糖果。
于是又想从右向左遍历,对于糖果数小于1个的做处理,此时发现很难通过一次遍历处理好。于是只能看答案了。

答案直接指出问题:“这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼。”

正确方法:

  1. 从左向右遍历,只关注右边评分大于左边的情况
  2. 从右向左遍历,只关注左边评分大于右边的情况
    但是为保证同时大于两边,取当前糖果数和第一次遍历得到的糖果数的最大值

因此通过两次局部最优,得到了全局最优

代码

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;
    }
};
posted @ 2024-12-17 11:08  NeroMegumi  阅读(4)  评论(0编辑  收藏  举报