135. 分发糖果 C++

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

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

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

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

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

提示:

n == ratings.length
1 <= n <= 2 * 10^4
0 <= ratings[i] <= 2 * 10^4

ans1. 

用两个数组保存

执行用时:20 ms, 在所有 C++ 提交中击败了54.36%的用户

内存消耗:19.3 MB, 在所有 C++ 提交中击败了5.00%的用户

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size();

        // 相邻两个孩子评分更高的孩子会获得更多的糖果
      
<think>好的,我现在需要解决用户的问题,即介绍C++中的分发糖果问题。首先,我要理解这个问题的大致内容。分发糖果通常是指LeetCode上的一个题目,题目描述是孩子们排成一排,每个孩子有一个评,要求按照一定规则分发糖果,使得每个孩子至少有一个糖果,且评更高的孩子必须比相邻孩子获得更多的糖果。最终要计算最少需要多少糖果。 接下来,我需要回忆这个题目的具体要求解决方法。通常,这个问题可以通过两次遍历来解决:一次从左到右,确保右边更高的孩子左边多;另一次从右到左,处理左边更高的孩子。然后将两次遍历的结果取最大值,总即为最少糖果数。 我需要用C++来实现这个算法,所以要考虑如何编写代码。首先,定义一个数组来存储每个孩子糖果数,初始化为1。然后进行两次遍历:第一次从左到右,如果右边高,则右边孩子糖果数为左边加一;第二次从右到左,如果左边高,则左边孩子糖果数取当前值右边加一的最大值。最后累加所有糖果数。 在解释过程中,要确保符合用户给出的系统级指令,比如数学表达式用$...$,独立公式用$$...$$,并且使用中文。需要注意代码部是否需要用LaTeX排版,但可能直接使用代码块更合适,不过用户没有特别说明,可能需要询问,但根据问题描述,用户可能更希望看到代码示例。 现在需要检查是否有遗漏的情况,比如所有孩子相同的情况,或者评递增或递减的情况。比如评是[1,2,3],那么分发应该是1,2,3,总6;如果评是[3,2,1],则分发3,2,1,总6。如果评是[1,3,4,5,2],则需要正确处理好峰值的情况。 在编写代码时,要注意数组的初始化,两次遍历的顺序,以及最后的累加。可能需要测试几个例子来验证代码的正确性。 现在组织回答的结构:先介绍问题,再步骤解释解决方法,然后给出代码示例,最后析时间复杂度可能的优化点。确保结构清晰,步骤明确,符合用户的要求。 需要确认是否所有数学表达式都正确使用了$符号,例如在说明条件时,比如右边的评左边高,即ratings[i] > ratings[i-1],可能需要写成$ratings[i] > ratings[i-1]$,但实际代码中可能不需要数学表达式,所以可能不需要。但如果有提到变量,比如评数组,可以用$ratings$表示。 最后,确保回答使用中文,语法正确,LaTeX格式正确,并且独立公式单独成段。不过在这个问题中可能涉及的数学公式较少,主要是算法步骤代码,但如果有需要,比如计算糖果数的公式,可以用独立公式。</think>### C++实现分发糖果问题解析 #### 问题描述 给定一个长度为$n$的整数数组$ratings$,表示$n$个孩子的评。需按以下规则分发糖果: 1. 每个孩子至少1颗糖果 2.更高的孩子必须比相邻孩子获得更多糖果 求最少需要多少糖果。 #### 解决思路 采用**两次贪心遍历**策略: 1. **从左向右遍历**:确保右边孩子左边高时,糖果数更多 2. **从右向左遍历**:确保左边孩子右边高时,糖果数更多 #### 算法步骤 1. 初始化数组$candies$,每个元素为1 2. 左→右遍历:若$ratings[i] > ratings[i-1]$,则$candies[i] = candies[i-1] + 1$ 3. 右→左遍历:若$ratings[i] > ratings[i+1]$,则$candies[i] = \max(candies[i], candies[i+1] + 1)$ 4. 累加所有糖果数 #### 时间复杂度 $$O(n)$$ 仅需两次线性遍历,时间复杂度为线性级别 --- ### C++代码实现 ```cpp #include <vector> #include <algorithm> using namespace std; int candy(vector<int>& ratings) { int n = ratings.size(); if(n == 0) return 0; vector<int> candies(n, 1); // 从左向右遍历 for(int i = 1; i < n; ++i) { if(ratings[i] > ratings[i-1]) { candies[i] = candies[i-1] + 1; } } // 从右向左遍历 for(int i = n-2; i >= 0; --i) { if(ratings[i] > ratings[i+1]) { candies[i] = max(candies[i], candies[i+1] + 1); } } // 累加结果 int total = 0; for(int num : candies) { total += num; } return total; } ``` --- ### 实例验证 例1:输入$ratings = [1,0,2]$ - 第一次遍历后:$[1,1,2]$ - 第二次遍历后:$[2,1,2]$ - 总数:$2+1+2=5$ 例2:输入$ratings = [1,3,4,5,2]$ - 第一次遍历后:$[1,2,3,4,1]$ - 第二次遍历后:$[1,2,3,4,1]$(右遍历无变化) - 总数:$1+2+3+4+1=11$ --- ### 关键点说明 1. **双向遍历必要性**:仅单方向遍历无法处理递减序列 2. **取最大值操作**:保证同时满足左右两边约束条件 3. **空间复杂度优化**:可将数组改为单个变量,但会降低代码可读性 此解法严格满足题目要求,且是最优时间复杂度解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值