[leetcode 9] candy

17 篇文章 0 订阅

题目描述
有N个小朋友站在一排,每个小朋友都有一个评分
你现在要按以下的规则给孩子们分糖果:

  • 每个小朋友至少要分得一颗糖果
  • 分数高的小朋友要他比旁边得分低的小朋友分得的糖果多

你最少要分发多少颗糖果?
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?

思路:

  • 要求返回最少的糖果个数,那就必须找到最少分配的方案。所以可以用一个整型的vector来存储每一个小朋友分得的糖果个数;
  • 因为每个小朋友都至少要分得一颗糖果,所以先初始化每个小朋友分得的糖果个数为1个;
  • 从左到右扫描,设扫描过的已经是最优分配方案,每个小朋友都和自己左边的小朋友比评分,有三种情况:
  • 1、当前小朋友比左边的小朋友评分高:因为左边扫描过的已经是最优方案了,所以当前小朋友的苹果个数只需比自己左边的小朋友多1就可以了;
  • 2、当前小朋友和左边的小朋友评分一样:题目要求如果得分高则分的苹果更多,没有说评分相同的情况,所以为了分最少的苹果,给当前小朋友分1个就好了,不会影响之前分好的小朋友;
  • 3、当前小朋友比左边的小朋友评分低:先对比当前小朋友和左边小朋友的苹果数量,如果不比左边的苹果少,则左边小朋友的苹果数量应该增加,因为当前小朋友的苹果数量不能小于1。但如果左边的小朋友的苹果数量变化了可能会影响更前面的小朋友,所以要一直更新直到符合要求。
  • 这样扫描过一遍之后,只需把所有小朋友的苹果数加起来就是结果。

完了,想着想着把糖果想成苹果了!你们知道是一个东西就行了^ ^

代码:

class Solution {
public:
    int candy(vector<int> &ratings) {
        int num = ratings.size(); 
        int res = 0;
        vector<int> apple(ratings.size(), 1); // 每个小朋友的苹果数量,默认是1
        for (int i=1; i<num; i++)
        {
            if (ratings[i] > ratings[i-1]) // 情况1:当前小朋友的评分比左边的高
                apple[i] = apple[i-1]+1;
            /*情况2不需要另外考虑,因为默认的苹果数量就是1*/
            else // 情况2,3:
            {
                int index = i;
                while (index > 0 && ratings[index] < ratings[index-1] && apple[index] >= apple[index-1]) // 不断更新直到符合条件
                {
                    apple[index-1]++;
                    index--;
                }
            }
        }
        for (int i=0; i<num; i++)
            res += apple[i];
        return res;
    }
};

有点难理解的话可以自己画几个小朋友,模拟一下,理解一下扫描的过程~

大佬们的代码:

#include <vector>
using namespace std;
class Solution {
public:
 
int candy(vector<int> &ratings) {
        //题意:N个孩子站成一排,每个孩子分配一个分值。给这些孩子派发糖果,满足如下要求:
        //每个孩子至少一个
        //分值更高的孩子比他的相邻位的孩子获得更多的糖果
        //求至少分发多少糖果?
        int len=ratings.size();
        if(len==1) return 1;
          
        int sum=0;
        vector<int> v(len,1);//初始将每个孩子的糖果数都设为1
          
        //从左向右扫描,保证一个方向上分数更大的糖果更多
        for(int i=1;i<len;i++){
            if(ratings[i] > ratings[i-1])
                v[i]=v[i-1]+1;
        }
        //从右向左扫描,保证另一个方向上分数更大的糖果更多
        for(int i=len-2;i>=0;i--){
            if(ratings[i] > ratings[i+1] && v[i] <= v[i+1])
                v[i]=v[i+1]+1;
        }
          
        for(int i=0;i<len;i++){
            sum+=v[i];
        }
        return sum;
    }
};

大佬们从来不会让我失望~ 哈哈哈,厉害!
思路大佬在注释里已经解释的很清楚了,我就不复述了~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值