[LeetCode] 135. 分发糖果
题目链接 : https://leetcode-cn.com/problems/candy/
题目描述:
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻的孩子中,评分高的孩子必须获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
示例:
示例 1:
输入: [1,0,2]
输出: 5
解释: 你可以分别给这三个孩子分发 2、1、2 颗糖果。
示例 2:
输入: [1,2,2]
输出: 4
解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果.
第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
思路:
思路一:
我们先找从左到右满足最少的糖果, 再找从右到左的, 最后取两边都满足的值(就是最大值)
大家可以自行优化一下!
思路二:只需扫一遍数组
如何判断i位置需要多少糖果, 我们需要处理有三种情况:
ratings[i - 1]==ratings[i], 那么我们只需要1糖果

ratings[i - 1] < ratings[i], 那么我们只需要比前一个多一块糖果

ratings[i - 1] > ratings[i], 那么我们不知道如何判断了比如:

但是, 如果知道递减的个数, 我们就能判断最少的糖果了

所以我们保证, 递减序列,是从 1开始加的(方向加),
再举个例子:
如何判读?的糖果多少, 我们发现ratings是3 - 2递减的,递减序列个数des_num为2,我们反向加,
有公差为1的求和公式\(首项尾项项数\frac{(首项 + 尾项) * 项数}{2}\),所以我们先假设rating在等于4时候也是满足等差的,所以 有\(\frac{( 1 + des\_num ) * des\_num}{2} = \frac{(1 + 2) * 2}{2}\) 糖果,所以ratings是3 - 2对于的糖果说2 - 1
但是还有一种可能, 如下图所示

大家在根据代码理解理解, 如果还有不明白的,可以提出来!
代码:
思路一:
def candy(self, ratings) -> int:
n = len(ratings)
if n == 0: return 0
left_to_right = [1] * n
right_to_left = [1] * n
# 找从左到右满足条件的
for i in range(1, n):
if ratings[i] > ratings[i - 1]:
# 保证从左到右的最少个数
left_to_right[i] = left_to_right[i - 1] + 1
# print(left_to_right)
# 找从右到左满足条件的(同时要符合从左到右)
for i in range(n - 2, -1, -1):
if ratings[i] > ratings[i + 1]:
# 保证从左到右也满足, 同时也满足从右到左
right_to_left[i] = max(left_to_right[i], right_to_left[i + 1] + 1)
# print(right_to_left)
res = 0
# 选这个位置最大值
for i in range(n):
res += max(left_to_right[i], right_to_left[i])
return res
优化思路一:
class Solution:
def candy(self, ratings: List[int]) -> int:
n = len(ratings)
if n == 0: return 0
candy_nums = [1] * n
for i in range(1, n):
if ratings[i] > ratings[i - 1]:
candy_nums[i] = candy_nums[i - 1] + 1
for i in range(n - 1, 0, -1):
if ratings[i - 1] > ratings[i]:
candy_nums[i - 1] = max(candy_nums[i - 1], candy_nums[i] + 1)
return sum(candy_nums)
java
class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0) return 0;
int n = ratings.length;
int[] candy_nums = new int[n];
Arrays.fill(candy_nums, 1);
for (int i = 1; i < n; i++) {
if (ratings[i] > ratings[i - 1]) candy_nums[i] = candy_nums[i - 1] + 1;
}
for (int i = n - 1; i > 0; i--) {
if (ratings[i - 1] > ratings[i]) candy_nums[i - 1] = Math.max(candy_nums[i - 1], candy_nums[i] + 1);
}
int res = 0;
for (int i = 0; i < n; i++) res += candy_nums[i];
return res;
}
}
思路二:
class Solution:
def candy(self, ratings: List[int]) -> int:
res = 1
# 先前值
pre = 1
# 递减长度
des_num = 0
for i in range(1, len(ratings)):
if ratings[i] >= ratings[i - 1]:
if des_num > 0:
# 求和公式
res += ((1 + des_num) * des_num) // 2
# 递减长度比先前值大,所以我们要把先前值补充
if pre <= des_num: res += (des_num - pre + 1)
pre = 1
des_num = 0
if ratings[i] == ratings[i - 1]:
pre = 1
else:
pre += 1
res += pre
else:
des_num += 1
# print(des_num)
if des_num > 0:
res += ((1 + des_num) * des_num) // 2
if pre <= des_num: res += (des_num - pre + 1)
return res
java
class Solution {
public int candy(int[] ratings) {
int res = 1;
int pre = 1;
int des_num = 0;
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] >= ratings[i - 1]) {
if (des_num > 0) {
res += ((1 + des_num) * des_num) / 2;
if (des_num >= pre) res += (des_num - pre + 1);
pre = 1;
des_num = 0;
}
pre = ratings[i - 1] == ratings[i] ? 1 : pre + 1;
res += pre;
} else des_num++;
}
if (des_num > 0) {
res += ((1 + des_num) * des_num) / 2;
if (des_num >= pre) res += (des_num - pre + 1);
}
return res;
}
}
[LeetCode] 135. 分发糖果的更多相关文章
- Java实现 LeetCode 135 分发糖果
135. 分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果. ...
- leetcode 135分发糖果
这是一道hard题,不好想,但最后还是想出来了,私以为还是根据一些思想方法自己想出来做法印象比较深刻,其次看人家的做法思想自己写代码,其次看代码理解默写,其次直接抄代码: 首先,给每个孩子都发一个糖果 ...
- LeetCode 135——分发糖果
1. 题目 2. 解答 初始化左序奖赏全为 1,从左往右遍历,如果右边的人评分比左边高,右边奖赏比左边奖赏增 1. 初始化右序奖赏全为 1,从右往左遍历,如果左边的人评分比右边高,左边奖赏比右边奖赏增 ...
- LeetCode:135. 分发糖果
LeetCode:135. 分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分 ...
- Leetcode 135.分糖果
分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果. 相邻的孩 ...
- 【LeetCode】分发糖果
[问题]老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果.相邻的孩子中 ...
- [Swift]LeetCode135. 分发糖果 | Candy
There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...
- [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现
[LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...
- LeetCode:分发饼干【455】
LeetCode:分发饼干[455] 题目描述 假设你是一位很棒的家长,想要给你的孩子们一些小饼干.但是,每个孩子最多只能给一块饼干.对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的 ...
随机推荐
- 【方法】原生js实现方法ajax封装
/* 参数说明* type[String] 请求方式('POST'或'GET') 默认设置'GET'方式* dataType[String] 获取到的后台数据格式 默认'JSON'格式* async[ ...
- 实战build-react(二)-------引入Ant Design(增加)
https://blog.csdn.net/zhan_lijian/article/details/85271906(copy) 1.肯定参考facebook关于react官网咯 快速搭建 creat ...
- 命令行创建 vue 项目(仅用于 Vue 2.x 版本)
1 .安装 Node.js 和 npm ( 验证安装成功输入下图 1 命令行可得 2:输入命令行 3 可得 4 即安装成功) 2.安装全局 webpack (安装依照下图输入命令行 1 耐心等待至到出 ...
- MySQL的(@i:=@i+1)用处及用法
今天写一个为查询的数据排序列号的SQL语句,整理出来下面的笔记: 这是语法: SELECT (@i:=@i+1),t.* FROM table_name t,(SELECT @i:=0) AS j ...
- Windows下启动.Net Core程序脚本
@echo offstart cmd /k "cd /D %~dp0&&dotnet xxx.dll" cmd /k 是执行完dir命令后不关闭命令窗口 cd /d ...
- jQuery file upload上传图片出错分析
以https://github.com/blueimp/jQuery-File-Upload/blob/master/basic-plus.html为例 注释掉load-image.all.min.j ...
- 微信小程序 API 路由
路由:由于页面的跳转: wx.switchTab() 跳转到 tabBar 页面,并关闭掉其他所有非 tabBar 页面: 参数:为对象, 对象的属性: url:需要跳转的 tabBar 的页面路径( ...
- maven 成长之路
1配置maven 环境变量 新建系统变量 M2_HOME :E:\apache-maven-3.5.2 在系统变量 path中添加 E:\apache-maven-3.5.2\bin 运行 mvn - ...
- DeepFaceLab报错,integer division or modulo by zero
DeepFaceLab的集成环境在众多换脸软件中是做的最好的.但是使用过程也会出现一些错误,主要的错误有两个,一个是你配置太低OOM了,主要体现显存太低.第二个是版本不对应.比如你原先用的cuda9. ...
- 移动端自动化==>Appium定位方式总结
1.ID Android Android的resource-id对应ID定位方式,可以通过index来获取需要的元素(从0开始查找dom树中的同名resource-id属性).使用appium-des ...