【Candy】cpp

题目

There are N children standing in a line. Each child is assigned a rating value. 

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

代码

复制代码
class Solution {
public:
    int candy(vector<int>& ratings) {
            const size_t len = ratings.size();
            std::vector<int> candyNum(len);
            // from left to right
            for (size_t i = 1; i < len; ++i){
                if (ratings[i] > ratings[i-1]) candyNum[i] = candyNum[i-1] + 1;
            }
            // from right to left
            for (size_t i = 1; i < len; ++i){
                if (ratings[len-i-1]>ratings[len-i]){
                    candyNum[len-i-1] = std::max(candyNum[len-i]+1,candyNum[len-i-1]);
                }
            }
            return std::accumulate(candyNum.begin(), candyNum.end(), len);
    }
};
复制代码

Tips:

大体思路是greedy。题目的需求可以分解为如下两个条件:

a. ratings从左向右的子递增序列,candy也要是递增的

b. ratings从右向左的子递增序列,candy同样也是递增的

具体:

1. 从左往右遍历一次,保证从左→右的递增序列,candy都是递增1的(相当于先对条件a进行了一次greedy,保证了条件a是充分的)

2. 从右往左遍历一次,保证从右→左的递增序列,candy也是至少递增1的(相当于再对条件b进行了一次greedy,保证了条件b是充分的,但是不能破坏条件a成立)

代码中一条关键语句如下:

std::max(candyNum[len-i]+1,candyNum[len-i-1]);

举个例子,ratings = {4,2,3,4,1}

从左往右走完第一遍 则candyNum = {0,0,1,2,0}

现在开始从右往左走,如果没有max这条语句,则走完右数第二个元素就变成了 candyNum = {0,0,1,1,0}

这样为了满足条件b就破坏了条件a,所以max这条语句是必要的。

从总体思路上来说:两个greedy并不能直接得到全局的最优解,需要调节两个greedy之间的矛盾,而max这条语句就是调节矛盾的

================================================

第二次过这道题,大体思路记得比较清楚,就是红字的部分,两个greedy之间不能破坏彼此的条件。

复制代码
class Solution {
public:
    int candy(vector<int>& ratings) {
            vector<int> candys(ratings.size(),1);
            // from left to right
            for ( int i=1; i<ratings.size(); ++i )
            {
                if ( ratings[i]>ratings[i-1] ) candys[i] = candys[i-1]+1;
            }
            // from right to left
            for ( int i=ratings.size()-1; i>0; --i )
            {
                if ( ratings[i-1]>ratings[i] )
                {
                    candys[i-1] = std::max( candys[i-1], candys[i]+1 );
                }
            }
            return accumulate(candys.begin(), candys.end(), 0);
    }
};
复制代码

 

posted on   承续缘  阅读(230)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示