LeetCode - 135. 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?
Example 1:
Input: [1,0,2] Output: 5 ( 2, 1, 2 )
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.
Example 2:
Input: [1,2,2] Output: 4 ( 1, 2, 1 )
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively. The third child gets 1 candy because it satisfies the above two conditions.
就是如果自己的分比邻居高,那糖就要比他多,但是要注意两个分一样高的人,不需要糖一样多。
所以可以直接从左到右一次遍历,让所有分高的人,糖比左边的人多 1,由于有上边的例子2这种情况,所以所有人初值都是 1。然后再从右向左一次遍历,让所有分比右边人高的人,糖要比右边的人多 1。由于所有人的糖都是只增不减,所以贪心是对的。AC代码如下:
int candy(const vector<int>& ratings) {
const int num = ratings.size();
if (num <= 1) return num;
vector<int> candies(num, 1);
for (int i = 1; i < num; ++i)
if (ratings[i] > ratings[i - 1])
candies[i] = candies[i - 1] + 1;
for (int i = num - 2; i >= 0; --i)
if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1])
candies[i] = candies[i + 1] + 1;
return accumulate(candies.begin(), candies.end(), 0);
}
实际遇到的面试题,是 n 个人站成一圈,然后其他条件和上边的题一模一样,只不过就是上边是一排,这里是一圈。既然是一圈,首尾就需要特殊判断了。
int candy(const vector<int>& ratings) {
const int num = ratings.size();
if (num <= 1) return num;
vector<int> candies(num, 1);
for (int i = 0; i < num; ++i) {
const int left = i == 0 ? (num - 1) : i - 1;
if (ratings[i] > ratings[left])
candies[i] = candies[left] + 1;
}
for (int i = num - 1; i >= 0; --i) {
const int right = i == (num - 1) ? 0 : i + 1;
if (ratings[i] > ratings[right] && candies[i] <= candies[right])
candies[i] = candies[right] + 1;
}
return accumulate(candies.begin(), candies.end(), 0);
}
这样,1 2 2 这个例子就是输出 5 而不是 4 了。