发糖果

力扣题目链接(opens new window)

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

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

  • 每个孩子至少分配到 1 个糖果。
  • 相邻的孩子中,评分高的孩子必须获得更多的糖果。

那么这样下来,老师至少需要准备多少颗糖果呢?

示例 1:

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

示例 2:

  • 输入: [1,2,2]
  • 输出: 4
  • 解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这已满足上述两个条件。

思路

根据示例1、2来看,我们只需要对满足规则的两种情况发放糖果即可,目标是在满足规则的前提下消耗最少的糖果(因此发的糖果数量有可能是不公平的)

怎么做呢?其实也简单,就是遍历数组,比较前后元素的大小关系,由此分配糖果即可

但是细想一下,遍历过程也是有坑的

举个例子:

从左往右遍历ratings数组,得到每个小孩应该分配的糖果数【左边孩子与右边孩子相比得出的结果】

此时的贪心:

局部最优:只要右边评分比左边大(ratings[i] > ratings[i - 1]),右边的孩子就多一个糖果

全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果

//从左往右遍历ratings数组,左边孩子与右边孩子相比
for(int i = 1; i < ratings.size(); ++i){//从下标1开始
if((ratings[i] > ratings[i - 1]) candyCount[i] = candyCount[i - 1] + 1;
}

但是,下标4和5位置,下标5的评分比4低,但是获得的糖果数一样,这不满足规则

所以还要从右往左遍历一遍【右边孩子与左边孩子相比得出的结果】,综合之后取最大值得出要分配的糖果数

此时的贪心:

局部最优:只要左边评分比右边大(ratings[i] > ratings[i + 1]),左边的孩子就多一个糖果

全局最优:相邻的孩子中,评分高的左孩子获得比右边孩子更多的糖果

//从右往左遍历ratings数组,右边孩子与左边孩子相比
for(int i = ratings.size() - 2; i >= 0; --i){//从倒数第二个下标开始
if(ratings[i] > ratings[i + 1]){
candyCount[i] = max(candyCount[i + 1] + 1, candyCount[i]);//取当前糖果数与之前的最大值
}
}

在第二个循环中,当当前孩子的评分高于右边孩子时,当前孩子需要得到的糖果数应该是右边孩子已经获得的糖果数加上一颗糖果。但是由于在从左到右第一次遍历中已经分配了一部分糖果,所以当前孩子最少也会拿到和左边孩子一样多的糖果数,因此需要取 candyCount[i + 1] + 1 和 candyCount[i] 中的较大值作为当前孩子最终得到的糖果数。其中 candyCount[i + 1] + 1 表示右边孩子已经获得的糖果数加上一颗糖果, candyCount[i] 表示当前孩子之前分配的糖果数,也就是至少能够得到的糖果数。这样可以保证分配的糖果数满足题目要求,并且不浪费糖果数量。

注意:将右边孩子和左边孩子相比时,必须从右往左遍历,不能从左往右然后通过改下标的方式来比较

代码

本题仍然采用了两次贪心策略

  • 一次是从左到右遍历,只比较右边孩子评分比左边大的情况。
  • 一次是从右到左遍历,只比较左边孩子评分比右边大的情况。

两次贪心最终可以得到满足规则的糖果分配数

步骤如下:

1、创建糖果数统计数组

2、从左往右遍历ratings数组,左边孩子与右边孩子相比

3、从右往左遍历ratings数组,右边孩子与左边孩子相比

4、统计糖果数

class Solution {
public:
int candy(vector<int>& ratings) {
//定义糖果统计数组
vector<int> candyCount(ratings.size(), 1);//默认给一个糖
//从左往右遍历ratings数组,左边孩子与右边孩子相比
for(int i = 1; i < ratings.size(); ++i){//从下标1开始
if(ratings[i] > ratings[i - 1]) candyCount[i] = candyCount[i - 1] + 1;
} //从右往左遍历ratings数组,右边孩子与左边孩子相比
for(int i = ratings.size() - 2; i >= 0; --i){//从倒数第二个下标开始
if(ratings[i] > ratings[i + 1]){
candyCount[i] = max(candyCount[i + 1] + 1, candyCount[i]);
}
}
//统计糖果数
int res = 0;
for(int c : candyCount) res += c;
return res;
}
};

在第二个for循环中,遍历的是从右到左的顺序,所以需要从数组的最后一个元素的前一个元素开始,即从 ratings.size() - 2 的位置开始遍历。如果从最后一个元素开始遍历,那么就只能判断这个元素和它左边的元素之间的大小关系,而无法判断它和右边元素之间的大小关系,因为右边已经没有元素了。

【LeetCode贪心#07】分糖果(两个维度)的更多相关文章

  1. [LeetCode] Distribute Candies 分糖果

    Given an integer array with even length, where different numbers in this array represent different k ...

  2. LeetCode之小孩分糖果

    给定一群站好队的小孩而且按某项分值排名(姑且如果为年龄吧),年龄大的要比他身边年龄小的拿的糖要多.求怎么分配糖果使得分配的糖果数最少. 用一个数组从左到右再从右到左的遍历,向前遍历时若右边的比左边的大 ...

  3. [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现

    [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...

  4. LeetCode 1103. Distribute Candies to People (分糖果 II)

    题目标签:Math 题目让我们分发糖果,分的糖果从1 开始依次增加,直到分完. for loop可以计数糖果的数量,直到糖果发完.但是还是要遍历array 给people 发糖,这里要用到 index ...

  5. Java实现 LeetCode 575 分糖果(看看是你的长度小还是我的种类少)

    575. 分糖果 给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果.你需要把这些糖果平均分给一个弟弟和一个妹妹.返回妹妹可以获得的最大糖果的种类数. 示例 1: 输入 ...

  6. CSDN 分糖果算法的思路和求助

    昨天晚上 在csdn上做了一道分糖果的题目,我自个测的是没有问题,但是提交答案后,老失败,提示 你的程序正常运行并输出了结果,但是答案错误你的程序输出结果与测试数据中的输出结果不符 我先把自个思路说一 ...

  7. hunnu11543:小明的烦恼——分糖果

    Problem description   小明在班里一直是个非常公正的孩子.这点同学和老师都非常清楚,这不,老师每周都会从家里带来一些糖果.然后叫小明把糖果分给其它小朋友,但这个班里的同学都有一个非 ...

  8. 牛客 2018NOIP 模你赛2 T2 分糖果 解题报告

    分糖果 链接:https://www.nowcoder.com/acm/contest/173/B 来源:牛客网 题目描述 \(N\) 个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们. 从某个 ...

  9. 51nod——1402最大值、2479小b分糖果 (套路)

    1402最大值:正向从1到n,如果没有限制,就依次递增1,如果有限制,就取那个限制和递增到这的最小值.这样保证1和每个限制点后面都是符合题意的递增,但是限制点前面这个位置可能会有落差(之前递增多了). ...

  10. Leetcode(4)寻找两个有序数组的中位数

    Leetcode(4)寻找两个有序数组的中位数 [题目表述]: 给定两个大小为 m 和 n 的有序数组 nums1 和* nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O( ...

随机推荐

  1. [转帖]@nginx多server及使用优化(php)

    文章目录 ​ ​一.nginx多server优先级​​ ​ ​二.禁止IP访问页面​​ ​ ​三.nginx的包含include​​ ​ ​四.nginx 路径的alias和root​​ ​ ​1.配 ...

  2. [转帖]陈巍谈芯:NLP里比BERT更优秀的XLNet长什么样?

    https://zhuanlan.zhihu.com/p/447836322 ​ 目录 收起 一.XLNet的优势 1)独得AR与AE两大绝学 2)集成了Tansformer-XL 二.XLNet的结 ...

  3. expres实现登录与修改密码

    登录模块 如果登录的时候,昵称在数据库中查询的是不唯一值.需要提示用户登录失败. 即使用户密码输入正确. 然后将该消息通知相关人员,立即进行排查问题. var express = require('e ...

  4. axios文件上传和 Content-Type类型介绍

    Content-Type的作用是什么? Content-Type: 用于在请求头部指定资源的类型和字符编码. 请求头中的content-type,就是 B端发给S端的数据类型描述 . 即告诉服务器端, ...

  5. 【分享一个工具】通过定义proto3来自动生成多进程模式的插件代码

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 我在多进程插件框架 hashicorp/go-plugin ...

  6. 无法下载安装文件,请检查internet连接

    win10 vs2019下提示visual studio installer无法下载安装文件,请检查internet连接     1.打开"网络和Internet设置",更改适配器 ...

  7. 🛠 开源即时通讯(IM)项目OpenIM源码部署指南

    OpenIM的部署涉及多个组件,并支持多种方式,包括源码.Docker和Kubernetes等.这要求在确保不同部署方式之间的兼容性同时,还需有效管理各版本之间的差异.确实,这些都是复杂的问题,涉及到 ...

  8. C/C++ 实现URL路径拆分

    URL路径拆分: 例如我们传入 http://www.baidu.com/index.php 拆分为 www.baidu.com 和 /index.php #include <Windows.h ...

  9. [MySQL] 给root用户设置权限

    mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'root'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'roo ...

  10. SpringCloud-05-Gateway

    统一网关Gateway 1.为什么需要网关 网关功能: 身份认证和权限校验 服务路由.负载均衡 请求限流 2.网关的技术实现 在SpringCloud中网关的实现包括两种: gateway zuul ...