leetcode-135. 分发糖果
贪心算法
分配问题
题目详情
n
个孩子站成一排。给你一个整数数组 ratings
表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到
1
个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
思路:
虽然这一道题也是运用贪心策略,但我们只需要简单的两次遍历即可:把所有孩子的糖果数初始化为 1;
先从左往右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的糖果数加 1;
再从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大于右边孩子的糖果数,则左边孩子的糖果数更新为右边孩子的糖果数加 1。
通过这两次遍历,分配的糖果就可以满足题目要求了。这里的贪心策略即为,在每次遍历中,只考虑并更新相邻一侧的大小关系。
我的代码:
C++
class Solution
{
public:
int candy(vector<int>& ratings)
{
int size=ratings.size();
if(size<2) //易忽略情况
return size;
vector<int> num(size,1); //将所有小孩先发放一个糖果
//两次遍历
for(int i=1;i<size;++i) //从左往右
//右边比左边高,则右边比左边额外给一个
{
if(ratings[i]>ratings[i-1])
num[i]=num[i-1]+1;
}
for(int j=size-1;j>0;--j) //从右往左
//与上一次不同,如果左边比右边高,则先验证左边糖果是否已经比右边多了
//因为第一次遍历可能已经满足他了,然后巧妙利用max来取得num[j-1]和num[j]+1的较大值给左边
{
if(ratings[j]<ratings[j-1])
num[j-1]=max(num[j-1],num[j]+1);
}
//std::accumulate函数可以简单求和,也可以用循环求和
return accumulate(num.begin(),num.end(),0);
}
};
Java
class Solution {
public int candy(int[] ratings) {
int size = ratings.length;
if (size < 2) return size;
int[] num = new int[size];
Arrays.fill(num,1);
for (int i = 1; i < size; ++i){
if (ratings[i] > ratings[i-1])
num[i] = num[i-1] + 1;
}
for (int j = size - 1; j > 0; --j){
if (ratings[j] < ratings[j-1])
num[j-1] = Math.max(num[j-1], num[j] + 1);
}
int ans = 0;
for (int n : num){
ans += n;
}
return ans;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)