135. Candy
题目大意
There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.
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.
Return the minimum number of candies you need to have to distribute the candies to the children.
中文释义
一排站着 n 个孩子。每个孩子都被分配了一个整数数组 ratings 中的评分值。
你需要给这些孩子分发糖果,但需遵守以下要求:
- 每个孩子至少分到一颗糖果。
- 评分更高的孩子比他们的邻居获得更多的糖果。
返回你需要拥有的最少糖果数量,以便将糖果分发给孩子们。
Example
Example 1:
- Input:
ratings = [1,0,2]
- Output:
5
- Explanation: 你可以分别给第一个、第二个和第三个孩子分发 2, 1, 2 颗糖果。
Example 2:
- Input:
ratings = [1,2,2]
- Output:
4
- Explanation: 你可以分别给第一个、第二个和第三个孩子分发 1, 2, 1 颗糖果。第三个孩子分到 1 颗糖果,因为它满足上述两个条件。
Constraints
n == ratings.length
1 <= n <= 2 * 10^4
0 <= ratings[i] <= 2 * 10^4
解题思路
算法描述
这段代码的目的是分配糖果给一排孩子,满足评分较高的孩子比其邻居获得更多的糖果。
-
首先初始化数组每个孩子获得糖果数为1。
-
从左至右遍历,判断当前孩子和左边的孩子相比,如果当前孩子评分更高,那么当前孩子比左边孩子糖果数多一个,如果当前评分孩子更低,不处理,交给下轮从右至左遍历处理。
-
从右至左遍历,判断当前孩子和右边的孩子相比,如果当前孩子评分更高,那么当前孩子的应该获得的糖果数应该是 当前孩子的糖果数和右边孩子糖果数+1 的 最大值。
算法的关键步骤如下:
-
初始化糖果数组:
- 创建一个与
ratings
大小相同的candies
数组,并将所有元素初始化为1,表示每个孩子最初得到一颗糖果。
- 创建一个与
-
从左至右遍历:
- 从第二个孩子开始遍历,对于每个孩子
i
,如果其评分比左边的孩子 (i - 1
) 高,那么将其糖果数设置为左边孩子的糖果数加1。
- 从第二个孩子开始遍历,对于每个孩子
-
从右至左遍历:
- 从倒数第二个孩子开始反向遍历,对于每个孩子
i
,如果其评分比右边的孩子 (i + 1
) 高,且当前糖果数不大于右边孩子的糖果数,则将其糖果数设置为右边孩子的糖果数加1。
- 从倒数第二个孩子开始反向遍历,对于每个孩子
-
计算总糖果数:
- 使用
accumulate
函数计算candies
数组中所有元素的总和,即为所需的最少糖果数量。
- 使用
-
返回结果:
- 返回计算出的糖果总数。
代码实现
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> candies(ratings.size(), 1);
for (int i = 1; i < ratings.size(); i++) {
candies[i] = ratings[i] > ratings[i - 1] ? candies[i - 1] + 1 : candies[i];
}
for (int i = ratings.size() - 2; i >= 0; i--) {
candies[i] = ratings[i] > ratings[i + 1] ? max(candies[i], candies[i + 1] + 1) : candies[i];
}
int sum = accumulate(candies.begin(), candies.end(), 0);
return sum;
}
};