贪心算法案例 - 分发糖果

贪心算法案例 - 分发糖果(Hard)

1. 题目描述

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。你需要按照以下要求,给这些孩子分发糖果:

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

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

2. 输出案例

输入是一个数组,表示孩子的评分。输出是最少糖果的数量。

Input: [1,0,2]

Output: 5

在上面的输入案例中,最少的糖果分法是[2, 1, 2]。

3. 分析

通常情况下我们认为解决贪心算法题目需要将对应的数组进行排序或者是选择,但是对于这道题来讲并不需要进行排序或者选择。我们只需要进行简单的遍历即可:

  • 首先将每个孩子的糖果数默认设置为1。
  • 先从左到右遍历一遍,如果右边孩子的分数大于左边孩子的分数,那么右边孩子获取到的糖果数为左边孩子糖果数+1。
  • 再从右往左进行遍历,如果左边孩子的糖果数大于右边孩子的糖果数,那么左边孩子的糖果数为 max(左边孩子糖果数,右边孩子糖果数+1),注意这里为什么不是"右边孩子糖果数+1"?这是因为这样做的话可能会破坏从左往右遍历已经确定好的糖果数分配!这里要特别注意。
  • 通过这两次遍历分配的糖果数就满足题目的要求了。

本题的贪心策略:在每次的遍历过程中,只考虑并更新相邻一侧的大小关系!

4. 代码

class Solution {
    public int candy(int[] ratings) {
        int count = 0;  // 统计总共糖果数

        int[] candies = new int[ratings.length];  // candies[i]表示第i个孩子获取到的糖果数字
        // 初始化每个孩子的糖果数为1
        for (int i = 0; i< candies.length; i++) {
            candies[i] = 1;
        }

        // 从左到右检查
        for (int i = 1; i< candies.length; i++) {
            if (ratings[i] > ratings[i-1]) {
                candies[i] = candies[i-1] +1;
            }
        }

        // 从右到左再检查一遍
        for (int i = ratings.length - 2; i >=0; i--) {
            if (ratings[i] > ratings[i+1]) {
                candies[i] = Math.max(candies[i+1] +1, candies[i]);
            }
        }

        for (int e: candies) {
            count += e;
        }

        return count;
    }
}
posted @   LilyFlower  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示