Candy - LeetCode

Candy - LeetCode

题目
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:
1.Each child must have at least one candy.
2.Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?


分糖只有两个要求,每个小朋友至少要有1颗糖,并且rating高的小朋友所得得到的糖要比站在他旁边的,rating比他低的小朋友多。
那么可以得到的信息:
如果一个小朋友的两边站的都是rating比他高的小朋友,那么只需要给他只给1颗糖
如果他旁边站着rating比他低的小朋友A,那么需要给他A小朋友所得糖数+1颗糖
如果他旁边站着的rating和他一样的小朋友,,这个题目里没说清楚,需要踩一下坑才知道什么情况

下面来说一下我的2B方法:
做题的时候可以逐个考虑(整体的方法我也想过,貌似不太方便),先从左边的小朋友开始给
(以下用v[k]来表示第k个小朋友得到的糖数,r[k]代表第k个小朋友的rating,共n个小朋友)

  1. 给第0个小朋友1颗糖, 令k=1
  2. 如果第k个小朋友的rating比第k-1个小朋友高,那么给他v[k-1]+1颗糖; 如果第k个小朋友的rating和第k-1个小朋友一样,那么给他1颗糖(踩完坑才知道只要给1颗); 如果第k个小朋友的rating比第k-1个小朋友低,那么给他1颗糖,令j = k,并跳到步骤4。
  3. k += 1。如果k < n跳到步骤2;如果k == n结束
  4. 如果r[j-1] <= r[j]或者v[j-1] > v[j],跳到步骤3;如果v[j-1] == v[j]并且r[j-1] > r[j],那么v[j-1] ++ ,j–,跳到步骤4(注:这里不可能出现v[j-1] < v[j]并且r[j-1]>r[j]的情况,因为执行完步骤3后,对任意k,v[k-1]都是大于v[k]的,所以即使v[k]加了1,最多也只能和v[k-1]相等,而不会大于)
class Solution {
public:
    int candy(vector<int>& ratings) {
        if (ratings[ratings.size()-1] < ratings[0])
            reverse(ratings.begin(),ratings.end());
        vector<int> v;
        v.assign(ratings.size(), 0);
        for (int i = 0; i < ratings.size(); i++) {
            if (i == 0) v[i]++;
            else {
                if (ratings[i] > ratings[i-1]) {
                    v[i] = v[i-1]+1;
                } else if (ratings[i] == ratings[i-1]) {
                    v[i] = 1;
                } else {
                    v[i] = 1;
                    if (v[i-1] == 1) {
                        for (int j = i-1; j >= 0; j--) {
                            if (ratings[j] > ratings[j+1] && v[j] == v[j+1]) {
                                v[j]++;
                            } else if (ratings[j] <= ratings[j+1]) {
                                break;
                            }
                        }
                    }
                }
            }
        }
        int sum = 0;
        for (int i = 0; i < v.size(); i++) {
            sum += v[i];
        }
        return sum;
    }
};

写完后看了下别人的代码,再一次觉得自己蠢爆。我的方法是每给一个小朋友发完糖,就回头检查一遍满不足满足条件,不满足就调整。人家的方法是先从左往右发糖,整个过程中始终满足如果r[k-1] < r[k]就有v[k-1] < v[k],如果r[k-1] >= r[k],那么v[k] = 1,遍历完之后,再从右往左调整。

class Solution {
public:
    int candy(vector<int>& ratings) {
        int len = ratings.size(), res = 0, i;
        if(len>0)
        {
            vector<int> number(len,0); // to save the number of candies for child[0:N-1]
            number[0] = 1; 
// forward scan to calculate how many candies needed for child i to make sure it has more candies than its left neighbor if it has a higher rate, otherwise, give one candy to it
            for(i=1; i<len;++i) number[i] = ratings[i]>ratings[i-1]?number[i-1]+1:1;

// backward scan to calculate to make sure child i has more candies than its right neighbor if it has a higher rate, pick the bigger one from forward and backward scans as the final number for child i
            for(i=len-2, res = number[len-1]; i>=0;--i)
            {
                if( (ratings[i]>ratings[i+1]) && number[i]<(number[i+1]+1) ) number[i] = number[i+1]+1;
                res += number[i];
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值