每日刷题:135.分发糖果

263 阅读1分钟

135.分发糖果(难度:困难)

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。 那么这样下来,老师至少需要准备多少颗糖果呢?

解题思路

  1. 把所有孩子的糖果数初始化为1;
  2. 先从左往右遍历,如果右边孩子的评分比左边的高,则将右边孩子的糖果数更新为左边孩子的糖果数+1;
  3. 从右往左遍历,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数 不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数+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}));
}