☆打卡算法☆LeetCode 135. 分发糖果 算法解析

177 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

推荐阅读

大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。

一、题目

1、算法题目

“给定一个整数数组表示一组孩子的评分,给一组孩子分发糖果,保证每个孩子至少有一个糖果,相邻孩子评分高的孩子得到更多糖果。”

题目链接:

来源:力扣(LeetCode)

链接: 135. 分发糖果 - 力扣(LeetCode)

2、题目描述

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

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

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

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

二、解题

1、思路分析

根据题意可知,相邻孩子中评分高的孩子糖果更多。

那么有两种情况,一种是左边的孩子评分高,一种是右边的孩子评分高。

遍历两边数组,计算每个孩子分别满足左边的孩子评分高和右边的孩子评分高两种情况下的需要分得糖果数量。

每个人的最终分得的糖果数量即为这两个数量中的最大值。

2、代码实现

代码参考:

class Solution {
    public int candy(int[] ratings) {
        int n = ratings.length;
        int[] left = new int[n];
        for (int i = 0; i < n; i++) {
            if (i > 0 && ratings[i] > ratings[i - 1]) {
                left[i] = left[i - 1] + 1;
            } else {
                left[i] = 1;
            }
        }
        int right = 0, ret = 0;
        for (int i = n - 1; i >= 0; i--) {
            if (i < n - 1 && ratings[i] > ratings[i + 1]) {
                right++;
            } else {
                right = 1;
            }
            ret += Math.max(left[i], right);
        }
        return ret;
    }
}

image.png

3、时间复杂度

时间复杂度:O(n)

其中n是孩子的数量,只需要遍历两次数组以分别计算出满足条件的答案。

空间复杂度:O(n)

其中n是孩子的数量,需要保存所有糖果数量。

三、总结

在实现代码时,先计算了满足左边的孩子评分高需要分得的糖果数量的数组left

在计算满足右边的孩子评分高需要分得的糖果数量的时候只需要用单个变量记录当前位置的变量,然后计算出答案即可。