LeetCode OJ 之 Candy (糖果数量)

题目:

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?

N个小孩站成一排,每个孩子有一个数字。为每个孩子分配糖果。有下面两个要求:

1、每个孩子至少一个糖果

2、如果这个孩子的数字比相邻的孩子的数字大,则糖果数要多于他的邻居。

问:至少要分配多少糖果?

思路:

1、两次遍历,求出每个孩子的糖果数量,然后相加

2、一次遍历,直接计算糖果总数。如果递增,则依次加上每一个(前一个糖果数量+1)。如果开始出现递减,则统计出递减的次数,详情见代码。

代码1:

class Solution {
public:
    int candy(vector<int>& ratings) 
    {
        int len = ratings.size();
        if(len <= 1)
            return len;
        int result = 0;
        vector<int> candy(len,1);
        //如果比前一个小孩的数值大,则糖数+1,否则默认为1
        for(int i = 1 ; i < len ; i++)
        {
            if(ratings[i] > ratings[i-1])
                candy[i] = candy[i-1] + 1;
        }
        
        //result先把最后一个小孩的糖数加上,因为由上面一个循环就可以得到最后一个小孩的糖数
        //如果最后一个比前一个小,则默认为1,如果比前一个大,则最后递增的可以确定下来
        result = candy[len-1];
        
        //逆序再遍历一遍,最后一个已经确定,由最后一个确定前面的
        for(int i = len-2 ; i >= 0 ; i--)
        {
            if(ratings[i] > ratings[i+1])
                candy[i] = max(candy[i+1]+1 , candy[i]);
            result += candy[i];
        }
        return result;
    }
};

代码2:

class Solution {
public:
    int candy(vector<int>& ratings) 
    {
        int len = ratings.size();
        if(len <= 1)
            return len;
        int result = 1;
        int cur = 1 , down = 0;//cur表示当前i应得的糖果数量,down表示递减的次数,如3,2,1,4 递减了2次
        for(int i = 1 ; i < len ; i++)
        {
            if(ratings[i] >= ratings[i-1])
            {
                if(down > 0)
                {
                    result += (1+down)*down / 2;//加上从down开始的地方到i-1,即糖果数量从down到1(等差数列和)
                    if(down >= cur)
                        result += down + 1 - cur;//如果递减开始的地方,即极大点比down小,则实际极大点的值应该是down+1,但是之前只加了cur,所以还要加上dowm-cur+1,比如数组1,5,4,3,2,1。前两个糖果数量按之前算的分别为1,2,后面四个是(4+1)*4/2=10,第三个4的糖果数量为4,因为之前第二个5的糖果数量当做2加上了,实际上应该是5个,所以应该再加上down + 1 - cur个糖果
                    down = 0;
                    cur = 1;
                }
                
                cur = ratings[i] == ratings[i-1] ? 1 : cur + 1;//求出当前i的糖果数量
                result += cur;//加上当前糖果数量
            }
            else
                down++;
        }
        if(down > 0)
        {
            result += (1+down)*down / 2;//如果后面递减,则加上最后的递减数列的糖果
            if(down >= cur)
                result += down - cur + 1;
        }
        return result;
    }
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值