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

发布时间 2024-01-05 08:56:38作者: 酷酷-

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;
    }
}

加油。