力扣第135题-分发糖果

955 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

前言

力扣第135题 分发糖果 如下所示:

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

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

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

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

示例 1:

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

示例 2:

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

一、思路

像这种贴近生活的题目,做起来还是非常有趣的。我们先梳理一下题目中的重点信息,发糖果的规则:

  • 每人至少1个糖果
  • 相邻的两个人中,评分高的孩子有更多的糖果

此外,我们要知道目标是:计算最少需要的糖果

我们知道相邻某是一种相互的概念,例如 A与B相邻,B也与A相邻。如下图所示,就是 从左向右 看这个队列和 从右向左 看这个队列。

从左向右 image.png

从右向左 image.png

很明显发糖果也是相同的道理,我们不仅要满足从左向右的相邻孩子间评分高的糖果更多,从右向左也时同样的情况。此外,为了保证计算的结果是最少需要的糖果,我们每次新增的糖果数量为 1

举个例子

这里以示例中的 ratings = {1,3,4,5,2} 作为例子,如下图所示:

image.png

  1. 我们先从左到右发糖果,保证相邻右边评分高的孩子糖果多一个

image.png

得到的结果如下所示(绿色块为发的糖果数量)

image.png

  1. 从右向左,保证相邻左边评分高的孩子糖果多一个

因为没有碰到相邻的孩子中,左边孩子的评分比右边高但糖果少的情况,故糖果的数量无需更新。

image.png

  1. 最后返回发的糖果数量的总和即可,这一题中返回的结果为 11

二、实现

实现代码

实现代码与思路中保持一致,我们先从左向右发糖果,然后再从右向左发糖果。

    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] nums = new int[len];
        nums[0] = 1;
        // 从左往右:保证相邻右边评分高的孩子糖果多一个
        for (int i=1; i < len; i++) {
            if (ratings[i] > ratings[i-1]) {
                nums[i] = nums[i-1] + 1;
            } else {
                nums[i] = 1;
            }
        }
        int ret = nums[len-1];
        // 从右往左:保证相邻左边评分高的孩子糖果多一个
        for (int i=len-2; i >= 0; i--) {
            if (nums[i] <= nums[i+1] && ratings[i] > ratings[i+1]) {
                nums[i] = nums[i+1] + 1;
            }
            ret += nums[i];
        }
        return ret;
    }

测试代码

    public static void main(String[] args) {
        int[] ratings = {1,3,4,5,2};
        int[] r1 = {1,0, 2};
        int ret = new Number135().candy(ratings);
        System.out.println(ret);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~