糖果分发问题的解题过程 | 豆包MarsCode AI 刷题

97 阅读4分钟

糖果分发问题的解题过程

在编程练习中,算法题常常考察我们的思维能力和编程技巧。今天,我将通过豆包MarsCode AI 刷题(代码练习)题库中的一道经典问题来分享我的解题思路和心得。这道题目不仅考察了如何模拟实际问题的过程,还涉及了如何高效地处理循环和分配问题。

题目背景:

小S有一批糖果 candies,他打算将这些糖果分给排成一列的 n 个小朋友。糖果的分发规则如下:

  1. 第一个小朋友获得 1 颗糖果,第二个小朋友获得 2 颗糖果,依此类推,直到第 n 个小朋友获得 n 颗糖果。
  2. 然后回到队伍的起点,继续分糖果。第一个小朋友这次获得 n + 1 颗糖果,第二个小朋友获得 n + 2 颗,依此类推,直到第 n 个小朋友获得 2 * n 颗糖果。
  3. 重复上述过程,每次分发的糖果数增加 1,直到糖果分完。如果剩下的糖果数量不足以满足当前轮次分发的要求,则将所有剩余的糖果分给当前的小朋友。

目标:

你需要返回一个长度为 n 的数组,表示每个小朋友最终获得的糖果数。

解题思路:

这道题目的核心是理解糖果的分发规则,并且如何在分发过程中处理每轮的糖果数量递增和糖果不足时的特殊情况。我们可以通过模拟分发过程来逐步解决问题。

1. 初始化变量
  • result 数组用来存储每个小朋友最终得到的糖果数,初始值为 0。
  • candies_left 变量表示剩余糖果的数量,初始化为总糖果数。
  • round 变量表示当前是第几轮分发糖果。
2. 分发糖果

每一轮,我们需要从第 1 个小朋友开始依次分发糖果。第 i 个小朋友在第 k 轮获得的糖果数是 n*k + i + 1。如果当前糖果不够,剩余的糖果直接分配给当前小朋友,并结束分发。

3. 分发过程的细节

每一轮的分发需要依次检查每个小朋友是否能够获得他们该得到的糖果,如果剩余糖果不足以分发给某个小朋友,则将剩余的糖果全给这个小朋友,之后结束。

4. 结束条件

分发过程会持续,直到剩余糖果为零为止。

代码实现:

def distributeCandies(candies, n):
    # 初始化每个小朋友获得的糖果数
    result = [0] * n
    # 目前剩余的糖果数
    candies_left = candies
    # 当前轮次
    round = 0
    
    while candies_left > 0:
        # 本轮分配的糖果数量从 round*n+1 到 (round+1)*n
        for i in range(n):
            # 当前小朋友该得到的糖果数
            candy_count = round * n + (i + 1)
            if candies_left >= candy_count:
                result[i] += candy_count
                candies_left -= candy_count
            else:
                # 如果糖果不足以分给当前小朋友,直接分剩余的糖果
                result[i] += candies_left
                candies_left = 0
                break
        round += 1

    return result

代码详解:

  1. result = [0] * n: 初始化一个数组 result,用来存储每个小朋友最终获得的糖果数。
  2. candies_left = candies: 用来记录剩余的糖果数量,初始值为给定的糖果总数。
  3. while candies_left > 0: 在糖果还有剩余时进入循环,不断分发糖果。
  4. for i in range(n) : 在每一轮,逐个给每个小朋友分发糖果。
  5. candy_count = round * n + (i + 1) : 每个小朋友在当前轮次应该得到的糖果数。随着轮次的增加,每个小朋友的糖果数递增。
  6. if candies_left >= candy_count: 如果剩余糖果足够给当前小朋友,则分配给该小朋友,减少剩余糖果。
  7. else: 如果剩余糖果不足,则将所有剩余的糖果分给当前小朋友并结束循环。
  8. round += 1: 进入下一轮分发。

复杂度分析:

  • 时间复杂度O(candies),最坏情况下每颗糖果都需要分发一次。每次分发糖果的过程最多会遍历 candies 颗糖果,因此时间复杂度与糖果数成正比。
  • 空间复杂度O(n),需要一个数组来存储每个小朋友的糖果数量。数组的大小与小朋友的数量 n 成正比,因此空间复杂度为 O(n)

示例:

假设我们有 10 颗糖果,3 个小朋友: 假设我们有 10 颗糖果,3 个小朋友:

candies = 10
n = 3
print(distributeCandies(candies, n))

输出结果为 [5, 5, 0],表示:

  • 小朋友 1 和小朋友 2 各获得 5 颗糖果。
  • 小朋友 3 获得 0 颗糖果。

总结:

通过这道题目,我加深了对循环模拟问题的理解,尤其是在处理不完全分配时,如何准确地管理剩余糖果的数量。此外,这也是一个典型的“贪心策略”问题,即每次尽量分发尽可能多的糖果,直到分发完为止。

希望这篇文章能帮助大家在类似问题中找到解决思路,并通过代码实现掌握更多的算法技巧!