力扣135题---分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 

第一次尝试

        看到这个题目,我们首先想到的就是从左往右依次遍历,然后看它是不是比旁边两个孩子的分数高,如果分高就多发一个糖果,最后发的糖果量再加上孩子的总数量即可满足题目要求,代码如下:

int candy(int* ratings, int ratingsSize)
{
    int CandyNum = 0;    //多发的糖果数量
    for(int i = 0; i< ratingsSize; i++)
    {
        //从0开始,到孩子数量减1结束,不计算最后一位,因为最后一位无下一位
        if(i >= 0 && i < ratingsSize - 1 && ratings[i] > ratings[i + 1])
            CandyNum++;    //如果当前分数比下一个孩子分数高,则糖果+1
        //从1开始,到孩子数量结束,不计算第0位,因为第0位无上一位
        if(i > 0 && i < ratingsSize && ratings[i] > ratings[i - 1])
            CandyNum++;    //如果当前分数比前一个分数高,则糖果+1
    }
    return CandyNum + ratingsSize;    //返回多发的糖果数量+孩子总数

}

再看运行结果:

 造成这种差别的原因是第1个孩子分数为3,比旁边两位都高所以要多发2个糖果,但是题目要求返回最少的糖果数量,也就是说第0个孩子多发0个糖果,第1个孩子比第0个孩子高,多发1个糖果,比第2个孩子分数高,再多发1个糖果。此时重复了1个糖果,因为第1个孩子只需多发1个糖果,就可以满足比第0个孩子和第2个孩子糖果都多,因此我们需要把重复的糖果数量减去,代码如下:

int candy(int* ratings, int ratingsSize)
{
    int CandyNum = 0, GiveCandytimes = 0, RepeatCandy = 0;
    for(int i = 0; i< ratingsSize; i++)
    {
        if(i >= 0 && i < ratingsSize - 1 && ratings[i] > ratings[i + 1])
            {
                CandyNum++;
                //如果满足条件,给糖果次数加一             
                GiveCandytimes++;
            }
        if(i > 0 && i < ratingsSize && ratings[i] > ratings[i - 1])
            {
                CandyNum++;
                //如果满足条件,给糖果次数+1
                GiveCandytimes++;
            }
        //如果给糖果次数为2表示重复给1次,重复次数+1
        if(GiveCandytimes == 2)
            RepeatCandy++;
        //给糖果次数清零,方便下一次循环
        GiveCandytimes = 0;
    }
    //返回给糖果总数+孩子数量-重复给的糖果
    return CandyNum + ratingsSize - RepeatCandy;

}

再看运行结果:

 此时对于这个数组,又少发了两个糖果,原因是动态比较的问题,第1个孩子比第0个孩子分高,多发1个,第2个孩子比第1个孩子多,也是多发一个,但是题目要求相邻两个孩子分高的获得更多的糖果,因此第2个孩子要比第一个孩子还多,也就是多发两个,右边同理,此时要对代码进行改进,以保证要对糖果分配进行动态规划

我们可以从左往右依次遍历,如果下一个孩子分数比当前孩子高,就把下一个孩子的糖果数量用当前孩子的糖果数量+1,同理再从右往左依次遍历,原理一样,这样就实现了动态规划糖果

代码如下:

int candy(int* ratings, int ratingsSize)
{
    int GiveCandys = 0;
    //分配内存
    int *GiveCandy = (int *)malloc(ratingsSize * sizeof(int));
    GiveCandy[0] = 1;    //第0位给1个糖果
    for(int i = 0; i< ratingsSize - 1; i++)
    {   
        GiveCandy[i + 1] = 1;    //下一位给1个糖果
        if(ratings[i] < ratings[i + 1])    
            //如果满足条件,下一位的糖果数量等于当前糖果数量+1
            GiveCandy[i + 1] = GiveCandy[i] + 1;
    }
    for(int i = ratingsSize - 1; i > 0; i--)
    {
        if(ratings[i] < ratings[i - 1] && GiveCandy[i] >= GiveCandy[i - 1])
            //如果满足条件,上一位的糖果数量等于当前糖果数量+1
            GiveCandy[i - 1] = GiveCandy[i] + 1;
    }
    //遍历一遍计算糖果总数
    for(int i = 0; i < ratingsSize; i++)
        GiveCandys += GiveCandy[i];
    //返回糖果总数
    return GiveCandys;
}

再看输出结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值