135. 分发糖果
题目链接
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
-
每个孩子至少分配到
1
个糖果。 -
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
提示:
-
n == ratings.length
-
1 <= n <= 2 * 104
-
0 <= ratings[i] <= 2 * 104
解题思路
-
先确定右边评分大于左边评分的情况,即对 ratings 从前向后遍历。此时的局部最优:只要右边评分大于左边评分,右边孩子就比左边孩子多一颗糖;全局最优:相邻孩子中,评分高的右边孩子获得比左边孩子更多的糖果。
-
再确定左边评分大于右边评分的情况,即对 ratings 从后向前遍历。此时如果左边评分大于右边评分,不能直接让左边孩子的糖果数比右边孩子的糖果数多一颗,而当前左边孩子的糖果数量应该是右孩子的糖果数加1或原来左孩子的糖果数中的最大值。
-
C++
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; } };
JavaScript
var candy = function(ratings) { let candyVec = Array(ratings.length).fill(1); // 从前向后遍历 for (let i = 1; i < ratings.length; i++) { if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1; } // 从后向前遍历 for (let i = ratings.length - 2; i >= 0; i--) { if (ratings[i] > ratings[i + 1]) candyVec[i] = Math.max(candyVec[i], candyVec[i + 1] + 1); } let result = 0; for (let i = 0; i < candyVec.length; i++) { result += candyVec[i]; } return result; };