【算法】【线性表】【数组】分发糖果

1  题目

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

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

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

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

示例 1:

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

示例 2:

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

2  解答

错误的解法,错就错在考虑的点儿少了,不能只根据左边来决定当前小孩儿分的糖果数,还要考虑右边:

复制代码
class Solution {
    public int candy(int[] ratings) {
        // 判断数组为空或者长度为0 直接返回
        if (ratings == null || ratings.length == 0) {
            return 0;
        }
        // 每次至少需要分配 ratings.length 个,剩下的主要是满足糖果差
        // 每个小孩能分配的个数又取决于左右小孩的糖果数
        // 每个小孩能分配的个数
        int len = ratings.length;
        // 用来存放左侧小孩多给的糖果数
        int leftSon = 1;
        // index用来记录当前多给的小孩的下标,主要是判断是否多给的是否相邻,
        // 相邻就需要多给的基础上累加
        // 不相邻的话只需要多给1个即可
        int index = -1;
        // 用来求至少需要的糖果数
        int sum = len;
        for (int i = 0; i < len; i++) {
            int leftIndex = Math.max(i - 1, 0);
            int rightIndex = i + 1 >= len ? len - 1 : i + 1;
            // 如果自己比左右孩子的分数高,那么我就需要多给
            if (ratings[i] > ratings[leftIndex] || ratings[i] > ratings[rightIndex]) {

                // 如果相邻 多给leftSon + 1
                // 不相邻只多给1个即可
                if (i - index == 1) {
                    if (ratings[i] > ratings[leftIndex]) {
                        leftSon += 1;
                    } else if (ratings[i] == ratings[leftIndex]) {
                        leftSon = leftSon;
                    } else {
                        leftSon = 1;
                    }
                } else {
                    leftSon = 1;
                }
                sum += leftSon;
                // index 指向当前多给的小孩
                index = i;
            }
        }
        return sum;
    }
}
复制代码

来个双向遍历的:

复制代码
class Solution {
    public int candy(int[] ratings) {
        // 判断数组为空或者长度为0 直接返回
        if (ratings == null || ratings.length == 0) {
            return 0;
        }
        int len = ratings.length;
        // 左侧遍历
        int[] leftArr = new int[len];
        // 右侧遍历
        int[] rightArr = new int[len];

        leftArr[0] = 0;
        for (int i = 1; i < len; i++) {
            if (ratings[i] > ratings[i - 1]) {
                leftArr[i] = leftArr[i - 1] + 1;
            } else {
                leftArr[i] = 0;
            }

        }

        rightArr[len - 1] = 0;
        for (int i = len - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                rightArr[i] = rightArr[i + 1] + 1;
            } else {
                rightArr[i] = 0;
            }
        }
        System.out.println(Arrays.toString(leftArr));
        System.out.println(Arrays.toString(rightArr));

        int sum = ratings.length;
        for (int i = 0; i < len; i++) {
            sum += Math.max(leftArr[i], rightArr[i]);
        }
        return sum;
    }
}
复制代码

加油。

posted @   酷酷-  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示