135.分发糖果(难度:困难)
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。 那么这样下来,老师至少需要准备多少颗糖果呢?
解题思路
- 把所有孩子的糖果数初始化为1;
- 先从左往右遍历,如果右边孩子的评分比左边的高,则将右边孩子的糖果数更新为左边孩子的糖果数+1;
- 从右往左遍历,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数 不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数+1。
题解
public int findMinCandyCount(int[] ratings) {
int childCount = ratings.length;
int[] candy = new int[childCount];
Arrays.fill(candy, 1);
for (int index = 1; index < childCount; index++) {
if (ratings[index - 1] < ratings[index]) {
candy[index] = candy[index - 1] + 1;
}
}
int minCount = 0;
for (int index = childCount - 1; index > 0; index--) {
if (ratings[index - 1] > ratings[index]) {
candy[index - 1] = Math.max(candy[index - 1], candy[index] + 1);
}
minCount += candy[index];
}
minCount += candy[0];
return minCount;
}
测试
Candy candy = new Candy();
@Test
public void text_case1() {
Assertions.assertEquals(5, candy.findMinCandyCount(new int[]{1, 0, 2}));
}
@Test
public void test_case2() {
Assertions.assertEquals(4, candy.findMinCandyCount(new int[]{1, 2, 2}));
}
@Test
public void test_case3() {
Assertions.assertEquals(3, candy.findMinCandyCount(new int[]{1, 2}));
}
@Test
public void test_case4() {
Assertions.assertEquals(1, candy.findMinCandyCount(new int[]{2}));
}