题目:n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:(1)每个孩子至少分配到 1 个糖果。(2)相邻两个孩子评分更高的孩子会获得更多的糖果。请你给每个孩子分发糖果,计算并返回需要准备的最少糖果数目 。
本题需注意第二个条件,一个孩子获取的糖果数需要和左右两边的孩子相比较,而不能只和一边的孩子相比较。因此左右两边都需要贪心算法:
(1)从左到右
局部最优:只要右边评分比左边大,右边的孩子就多一个糖果
全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果
// 从前向后
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
}
(2)从右到左
局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量(candyVec[i]只有取最大的才能既保持对左边candyVec[i - 1]的糖果多,也比右边candyVec[i + 1]的糖果多。),保证第i个小孩的糖果数量既大于左边的也大于右边的
全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。(从右到左一定要从后向前遍历,因为左孩子大于右孩子的情况需要用上右孩子的比较情况)
// 从后向前
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1] ) {
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
}
}
整体代码如下:
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> candyVec(ratings.size(), 1);
// 从前向后
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
}
// 从后向前
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1] ) {
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
}
}
// 统计结果
int result = 0;
for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
return result;
}
};