135. 分发糖果

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

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

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

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

示例 2:

输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
     第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

提示:

  • n == ratings.length
  • 1 <= n <= 2 * 104
  • 0 <= 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;
    }

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

🛡️ 闽ICP备2024065179号-3