n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
1、分析过程
评分数组ratings :[5 , 4 , 6 , 2 , 4]
数组下标 : 0 1 2 3 4
计算 : [2 1 2 1 2]
结果 :2 + 1 + 2 + 1 + 2 = 8
评分数组ratings :[2 , 3 , 3 , 3 , 3]
数组下标 : 0 1 2 3 4
计算 :[1 2 1 1 1]
结果 :1 + 2 + 1 + 1 + 1 = 6
评分数组ratings :[2 , 3 , 3 , 2 , 1]
数组下标 : 0 1 2 3 4
计算 :[1 2 3 2 1]
结果 :1 + 2 + 2 + 3 + 1 = 9
2、解答过程(预处理)
评分数组ratings :[3 , 4 , 4 , 5 , 1 , 2 , 2 , 3 , 4 , 2 , 1]
数据下标 : 0 1 2 3 4 5 6 7 8 9 10
左坡辅助数组 :[1 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 3 , 1 , 1]
右坡辅助数组 :[1 , 1 , 1 , 2 , 1 , 1 , 1 , 1 , 3 , 2 , 1]
计算 :[1 , 2 , 1 , 2 , 1 , 2 , 1 , 2 , 3 , 2 , 1]
结果 :1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 3 + 2 + 1 = 18
注意:相同下标,左坡与右坡相比,取大的数
3、代码示例
import java.util.Arrays;
public class Code02_CandyProblem {
public static void main(String[] args) {
int[] arr = {3,4 , 4 , 5 , 1 , 2 , 2 , 3 , 4 , 2 , 1};
// [1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 1]
// 18
System.out.println(candy(arr));
}
public static int candy(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
int[] left = new int[N];
for (int i = 1; i < N; i++) {
if (arr[i - 1] < arr[i]) {
left[i] = left[i - 1] + 1;
}
}
int[] right = new int[N];
for (int i = N - 2; i >= 0; i--) {
if (arr[i] > arr[i + 1]) {
right[i] = right[i + 1] + 1;
}
}
int ans = 0;
int[] result = new int[N];
for (int i = 0; i < N; i++) {
ans += Math.max(left[i], right[i]);
// 因为数组默认值为0,而题目要求每人至少1个
result[i] = Math.max(left[i], right[i]) + 1;
}
// 每个人分到的糖果数
System.out.println(Arrays.toString(result));
// 因为数组默认值为0,而题目要求每人至少1个
return ans + N;
}
}