题目:
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?
题解:两种做法。
第一种:第一个小朋友发一块糖,以后每当后面的rating大,多发一块,rating小,少发一块,rating一样,只发一块。同时时刻更新当前最高rating和最低rating出现的位置,每当低位拐点时,重新计算整个递减区间的糖数。如果拐点糖 <= 0,从当前高位到拐点的每个人多发diff = 1 - 拐点糖数 个糖,若拐点糖 > 1,从高位的下一位到拐点,每个人减去diff = 拐点糖数 - 1 个糖。 记得适时更新当前高位和低位的位置。
第二种:
第一个小朋友发一块糖,以后每个人,只要rating大,就多发一块糖,否则,只发一块糖。这样一轮发糖结束后,我们能保证凡是rating大的在rating小的右边的小朋友糖数一定能满足要求,而且每个小朋友至少有一块糖。但是我们不能满足rating大的在rating小的左边的小朋友糖数满足条件。于是逆向更正一次。凡是rating[i] < rating[i-1],但是糖[i] >= 糖[i-1]的小朋友,rating[i-1] 增加为rating[i] + 1,于是正向反向均满足条件。
C++做法一:
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> number(ratings.size());
//vector<int> number;
//number.reserve(ratings.size());
number[0] = 1;
int high = 0, low = 0;
for(int i = 1; i < ratings.size(); i++) {
if(ratings[i] > ratings[i-1]) {
number[i] = number[i-1] + 1;
high = i;
}
else if (ratings[i] < ratings[i-1]) {
number[i] = number[i-1] - 1;
low = i;
}
else {
number[i] = 1;
high = low = i;
}
if(i < ratings.size()-1 && ratings[i] < ratings[i-1] && ratings[i+1] >= ratings[i]) {
if(number[i] <= 0) {
int diff = 1 - number[i];
for(int j = high; j <= low; j++)
number[j] += diff;
}
else if(number[i] > 1) {
int diff = number[i] - 1;
for(int j = high + 1; j <= low; j++)
number[j] -= diff;
}
high = low = i;
}
}
if(ratings[ratings.size()-1] < ratings[ratings.size()-2]) {
if(number[ratings.size()-1] <= 0) {
int diff = 1 - number[ratings.size()-1];
for(int j = high; j <= low; j++)
number[j] += diff;
}
else if(number[ratings.size()-1] > 1) {
int diff = number[ratings.size()-1] - 1;
for(int j = high + 1; j <= low; j++)
number[j] -= diff;
}
}
int sum = 0;
for(int i = 0; i < ratings.size(); i++) {
sum += number[i];
}
return sum;
}
};
Java做法二:
public class Solution {
public int candy(int[] ratings) {
if(ratings.length == 0)
return 0;
int[] number = new int[ratings.length];
number[0] = 1;
for(int i = 1; i < ratings.length; i++) {
if(ratings[i] > ratings[i-1])
number[i] = number[i-1] + 1;
else
number[i] = 1;
}
int sum = 0;
for(int i = ratings.length-1; i > 0; i--) {
if(ratings[i] < ratings[i-1] && number[i] >= number[i-1])
number[i-1] = number[i] + 1;
sum += number[i];
}
sum += number[0];
return sum;
}
}
Python做法一:
class Solution:
# @param {integer[]} ratings
# @return {integer}
def candy(self, ratings):
if len(ratings) == 0:
return 0
number = [0] * len(ratings)
number[0] = 1
high = 0
low = 0
for i in range(1,len(ratings)):
if ratings[i] > ratings[i-1]:
number[i] = number[i-1] + 1
high = i
elif ratings[i] < ratings[i-1]:
number[i] = number[i-1] - 1
low = i
else:
number[i] = 1
high = i
low = i
if i < len(ratings) - 1 and ratings[i] < ratings[i-1] and ratings[i] <= ratings[i+1]:
if number[i] > 1:
diff = number[i] - 1
for j in range(high+1, low+1):
number[j] -= diff
if number[i] <= 0:
diff = 1 - number[i]
for j in range(high, low+1):
number[j] += diff
if ratings[len(ratings)-2] > ratings[len(ratings)-1]:
if number[i] > 1:
diff = number[i] - 1
for j in range(high+1, low+1):
number[j] -= diff
if number[i] <= 0:
diff = 1 - number[i]
for j in range(high, low+1):
number[j] += diff
sum = 0
for i in range(0, len(ratings)):
sum += number[i]
return sum
Python做法二:
class Solution:
# @param {integer[]} ratings
# @return {integer}
def candy(self, ratings):
if len(ratings) == 0:
return 0
number = [0] * len(ratings)
number[0] = 1
for i in range(1, len(ratings)):
if ratings[i] > ratings[i-1]:
number[i] = number[i-1] + 1
else:
number[i] = 1
total = 0
for i in range(len(ratings)-1, 0, -1):
if ratings[i-1] > ratings[i] and number[i-1] <= number[i]:
number[i-1] = number[i] + 1
total += number[i]
total += number[0]
return total