n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2] 输出:5 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
提示:
n == ratings.length1 <= n <= 2 * 1040 <= ratings[i] <= 2 * 104
public int candy(int[] ratings) {
return method1(ratings, ratings.length);
}
/**
* 贪心算法
* 7 ms
* 复杂度O(n)
*/
public int method1(int[] ratings, int n) {
int[]nums = new int[n];
// 初始化赋值
Arrays.fill(nums, 1);
// 从左到右判断,右边大于左边,则右边的糖果数比左边多1
for (int i = 1 ; i < n ; i++) {
if (ratings[i] > ratings[i - 1] && nums[i] <= nums[i - 1]) {
nums[i] = nums[i - 1] + 1;
}
}
// 同理
for (int i = n - 2 ; i >= 0 ; i--) {
if (ratings[i] > ratings[i + 1] && nums[i] <= nums[i + 1]) {
nums[i] = nums[i + 1] + 1;
}
}
return Arrays.stream(nums).sum();
}
/**
* 贪心算法
* 2 ms
* 复杂度O(n)
*/
public int method2(int[] ratings, int n) {
int ans = n;
for (int i = 0; i < n; i++) {
// 起点
int start = i > 0 && ratings[i - 1] < ratings[i] ? i - 1 : i;
// 递增
while (i + 1 < n && ratings[i] < ratings[i + 1]) {
i++;
}
// 峰顶
int top = i;
// 递减
while (i + 1 < n && ratings[i] > ratings[i + 1]) {
i++;
}
// 递增区间
int inc = top - start;
// 递减区间
int dec = i - top;
// 峰顶的值为递增或递增的最大长度,其余依次递减
ans += (inc * (inc - 1) + dec * (dec - 1)) / 2 + Math.max(inc, dec);
}
return ans;
}
No responses yet