文章目录
- 一【题目类别】
- 二【题目难度】
- 三【题目编号】
- 四【题目描述】
- 五【题目示例】
- 六【解题思路】
- 七【题目提示】
- 八【时间频度】
- 九【代码实现】
- 十【提交结果】
一【题目类别】
- 贪心算法
二【题目难度】
- 困难
三【题目编号】
- 135.分发糖果
四【题目描述】
- n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
- 你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1 个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
- 请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
五【题目示例】
-
示例 1:
- 输入:ratings = [1,0,2]
- 输出:5
- 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
-
示例 2:
- 输入:ratings = [1,2,2]
- 输出:4
- 解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
六【解题思路】
- 这道题有难度,不太好想,主要利用贪心的思路遍历两次数组,分别从左到右遍历和从右到左遍历,也就是满足两个规则:
- 左规则:从左到右遍历,因为题目要求每个人最少一个糖果,所以第一个人默认一个糖果,然后从第二个人开始遍历,如果第 i i i个人的评分大于第 i − 1 i-1 i−1个人的评分,根据题目要求,第 i i i个人的糖果数要比第 i − 1 i-1 i−1个人的糖果数多一个;如果第 i i i个人的评分小于等于第 i − 1 i-1 i−1个人的评分,那么第 i − 1 i-1 i−1个人的糖果数就是默认的一颗糖果。当然,需要使用一个数组来存储每个人的糖果数
- 右规则:从右到左遍历,因为题目要求每个人最少一个糖果,所以最后个人默认一个糖果,然后从倒数第二个人开始遍历,如果第 i i i个人的评分大于第 i + 1 i+1 i+1个人的评分,根据题目要求,第 i i i个人的糖果数要比第 i + 1 i+1 i+1个人的糖果数多一个;如果第 i i i个人的评分小于等于第 i + 1 i+1 i+1个人的评分,那么第 i − 1 i-1 i−1个人的糖果数就是默认的一颗糖果。此时需要使用另一个数组来存储每个人的糖果数
- 最后计算总的糖果数,将上面的得到的数组进行遍历,对于第 i i i个人,既要满足左规则也要满足右规则,所以取两者中的最大值
- 最后返回结果即可
七【题目提示】
- n = = r a t i n g s . l e n g t h n == ratings.length n==ratings.length
- 1 < = n < = 2 ∗ 1 0 4 1 <= n <= 2 * 10^4 1<=n<=2∗104
- 0 < = r a t i n g s [ i ] < = 2 ∗ 1 0 4 0 <= ratings[i] <= 2 * 10^4 0<=ratings[i]<=2∗104
八【时间频度】
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为传入数组的长度
- 空间复杂度: O ( n ) O(n) O(n),其中 n n n为传入数组的长度
九【代码实现】
- Java语言版
class Solution {
public int candy(int[] ratings) {
int len = ratings.length;
int[] left = new int[len];
int[] right = new int[len];
left[0] = 1;
for(int i = 1;i < len;i++){
left[i] = ratings[i] > ratings[i - 1] ? left[i - 1] + 1 : 1;
}
right[len - 1] = 1;
for(int i = len - 2;i>=0;i--){
right[i] = ratings[i] > ratings[i + 1] ? right[i + 1] + 1 : 1;
}
int res = 0;
for(int i = 0;i<len;i++){
res += Math.max(left[i],right[i]);
}
return res;
}
}
- C语言版
int candy(int* ratings, int ratingsSize)
{
int* left = (int*)malloc(sizeof(int) * ratingsSize);
int* right = (int*)malloc(sizeof(int) * ratingsSize);
left[0] = 1;
for(int i = 1;i<ratingsSize;i++)
{
left[i] = ratings[i] > ratings[i - 1] ? left[i - 1] + 1 : 1;
}
right[ratingsSize - 1] = 1;
for(int i = ratingsSize - 2;i>=0;i--)
{
right[i] = ratings[i] > ratings[i + 1] ? right[i + 1] + 1 : 1;
}
int res = 0;
for(int i = 0;i<ratingsSize;i++)
{
res += fmax(left[i],right[i]);
}
return res;
}
- Python版
class Solution:
def candy(self, ratings: List[int]) -> int:
N = len(ratings)
left = [0] * N
right = [0] * N
left[0] = 1
for i in range(1,N):
left[i] = left[i - 1] + 1 if ratings[i] > ratings[i - 1] else 1
right[N - 1] = 1
for i in range(N - 2,-1,-1):
right[i] = right[i + 1] + 1 if ratings[i] > ratings[i + 1] else 1
res = 0
for i in range(0,N):
res += max(left[i],right[i])
return res
十【提交结果】
-
Java语言版
-
C语言版
-
Python语言版