刷刷刷 Day 34 | 135. 分发糖果

135. 分发糖果

LeetCode题目要求

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

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

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
解题思路

从左到右,如果右大于左,那么右边左多一个糖果,但此时能保证的是右大于左的情况
然后在从右刀座,如果右小于左,就再分配糖果,让左边的再+1,同时与原数量作对比,取大的。
本题通过局部最优,推出全局最优。需要两部走

上代码

class Solution {
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candyCountArr = new int[len];

        // 总共需要的数量
        int candyTotal = 0;

        // 初始位置第一个至少个 1 个 candy
        candyCountArr[0] = 1;
        for (int i = 1; i < len; i++) {
            // 如果右边的大于左边的,
            if (ratings[i] > ratings[i-1]) {
                // 那么右边的比左边的要多1个
                candyCountArr[i] = candyCountArr[i-1] + 1;
            } else {
                // 其他的一律默认给 1 个 candy
                candyCountArr[i] = 1;
            }
        }

        // 第二次遍历 处理右边小于左边的(左边大于右边), 从后遍历
        for (int i = len - 2; i >= 0; i--) {
            // 如果左大于右
            if (ratings[i] > ratings[i+1]) {
                // 从 candyCountArr[i+1] + 1, candyCountArr[i] 取大的,
                // 即 candyCountArr[i+1] 右侧小,那么左侧应该大于右侧,此时 +1 后就是左侧的值;但这时还要看新的值和原左侧的值,哪个个大,取大的
                candyCountArr[i] = Math.max(candyCountArr[i+1] + 1, candyCountArr[i]);
            }
        }

        for (int i = 0; i < len; i++) {
            candyTotal += candyCountArr[i];
        }

        return candyTotal;
    }
}

附:学习资料链接

posted @ 2023-02-19 23:18  blacksonny  阅读(16)  评论(0编辑  收藏  举报