1. 问题背景与核心挑战
糖果分配问题看似简单,实则暗藏玄机。想象你是一位班主任,要给排成一列的孩子们分发糖果,既要满足"成绩好的孩子要比邻座拿更多糖"的基本规则,又要考虑班级经费有限需要最小化糖果总量。这就是LeetCode 135题给我们出的难题。
这个问题的难点在于约束条件的双向性——每个孩子的糖果数需要同时满足与左右邻居的比较关系。当遇到连续递增或递减的分数序列时,简单的单向遍历就会失效。我在第一次尝试时,就因为没有考虑双向约束,导致提交的解法在测试用例[1,3,4,2,1]上翻了车。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路拆解
2.1 暴力法的局限
最直观的想法是暴力枚举所有可能的分配方案,检查是否满足条件后取最小值。但这种方法的时间复杂度是O(n^2),当n=10^5时完全不可行。我在本地测试时,仅n=20的case就需要近10秒才能跑完。
2.2 关键突破:双向遍历
经过多次尝试,我发现可以将问题分解为两个单向约束:
- 从左到右:保证右边分数高的孩子糖果更多
- 从右到左:保证左边分数高的孩子糖果更多
最终每个孩子的糖果数取这两个方向计算结果的较大值。这种方法将时间复杂度降到了O(n),空间复杂度O(n),完美满足题目要求。
3. 算法实现详解
3.1 初始化阶段
python复制def candy(ratings):
n = len(ratings)
left = [1] * n # 从左到右的分配
right = [1] * n # 从右到左的分配
每个孩子至少分到1颗糖,这是题目隐含的最小单位。在实际编码时,我最初忽略了这一点,导致边界条件处理出错。
3.2 左遍历处理
python复制for i in range(1, n):
if ratings[i] > ratings[i-1]:
left[i] = left[i-1] + 1
这里有个易错点:只有当右边分数严格大于左边时才增加糖果数。我第一次写成了>=,导致分数相等的孩子也被多分了糖,违反了最小化原则。
3.3 右遍历处理
python复制for i in range(n-2, -1, -1):
if ratings[i] >
