在今天的刷题中,遇到了这样一道题目,刚开始写的时候题目看错了,再加上自己的想法过于复杂,所以困扰了我很久
问题描述
小S有一批糖果 candies,他打算将这些糖果分给排成一列的 n 个小朋友。糖果的分发规则如下:
- 第一个小朋友获得 1 颗糖果,第二个小朋友获得 2 颗糖果,依此类推,直到第
n个小朋友获得n颗糖果。 - 然后回到队伍的起点,继续分糖果。第一个小朋友这次获得
n + 1颗糖果,第二个小朋友获得n + 2颗,依此类推,直到第n个小朋友获得2 * n颗糖果。 - 重复上述过程,每次分发的糖果数增加 1,直到糖果分完。如果剩下的糖果数量不足以满足当前轮次分发的要求,则将所有剩余的糖果分给当前的小朋友。
你需要返回一个长度为 n 的数组,表示每个小朋友最终获得的糖果数。
测试样例
样例1:
输入:
candies = 7 ,n = 4
输出:[1, 2, 3, 1]
样例2:
输入:
candies = 10 ,n = 3
输出:[5, 2, 3]
样例3:
输入:
candies = 20 ,n = 5
输出:[6, 2, 3, 4, 5]
初步的思路
- 首先,函数
solution的目的是根据给定的糖果总数candies和小朋友的数量n,来计算每个小朋友最终能得到的糖果数量。 - 计算每一轮分发糖果的总数
num_per_round,按照从1到n的等差数列求和公式n×(n+1)÷2得到。 - 然后确定轮数
num_rounds,这是通过糖果总数除以每轮分发总数得到的。然后计算出经过完整轮数分发后剩余的糖果数remaining_candies。 - 接着,在每一轮中按照一定规律给每个小朋友分配糖果。
- 最后,处理剩余的糖果,按照一定顺序逐个分配给小朋友,最后返回每个小朋友得到的糖果数量列表
result。
初步的代码
def solution(candies: int, n: int) -> list:
result = [0]* n
if n==1:
result=candies
return result
num_per_round = n*(n + 1)/2
num_rounds = int(candies/num_per_round)
remaining_candies = candies%num_per_round
for r in range(num_rounds):
for i in range(n):
result[i]+=i + 1+r*n
index = 0
while remaining_candies>0:
if remaining_candies>=index + 1+num_rounds*n:
result[index]+=index + 1+num_rounds*n
remaining_candies-=index + 1+num_rounds*n
else:
result[index]+=remaining_candies
remaining_candies = 0
index=(index + 1)%n
return result
初步的结果
题目中的输出案例都没错误,但是遇到了如下的错误
事实上按照题目中的逻辑来看,也不能说这个结果不对,但是既然答案说15,那就按照:如果只有一个人,就把糖果全部给他的思路。
修改后的代码
def solution(candies: int, n: int) -> list:
if n == 1:
return [candies]
result = [0]* n
num_per_round = n * (n + 1) // 2
num_rounds = candies // num_per_round
remaining_candies = candies % num_per_round
for r in range(num_rounds):
for i in range(n):
result[i] += i + 1 + r * n
index = 0
while remaining_candies > 0:
if remaining_candies >= index + 1 + num_rounds * n:
result[index] += index + 1 + num_rounds * n
remaining_candies -= index + 1 + num_rounds * n
else:
result[index] += remaining_candies
remaining_candies = 0
index = (index + 1) % n
return result
然后出现了这样的报错:
借助AI工具
实在不明白为什么,于是我借助了右侧的AI工具,帮我检查了一下代码问题出现在哪
并且给我指出了新的思路
最终的正确代码
def solution(candies: int, n: int) -> list:
res = [0]* n
i = 0
left = candies
while left > 0:
give = min(i + 1, left)
res[i%n]+=give
left -= give
i += 1
return res
if __name__ == '__main__':
print(solution(candies=7, n=4) == [1, 2, 3, 1])
print(solution(candies=10, n=3) == [5, 2, 3])
print(solution(candies=20, n=5) == [6, 2, 3, 4, 5])
最终的正确代码解释
-
初始化部分
- 函数
solution中创建了一个长度为n且元素都为0的列表res,用于存储每个小朋友最终得到的糖果数。同时初始化变量i = 0,它将用于表示当前分配糖果的轮次或者说索引,以及left = candies,表示还剩下的糖果数量。
- 函数
-
循环分配糖果部分
- 进入
while循环,只要还有糖果(left>0)就会一直循环。 - 在每次循环中,计算当前要分配给小朋友的糖果数量
give,它取i + 1(也就是按照1、2、3……这样的顺序来分配糖果的数量)和left(剩余的糖果数量)中的最小值。这样做是为了确保不会分配超过剩余糖果数量的糖果。 - 接着,将
give数量的糖果分配给第i%n个小朋友,这里使用i%n是为了循环遍历n个小朋友,当i超过n时可以重新回到第一个小朋友开始分配。 - 最后更新剩余的糖果数量(
left-=give)和轮次索引(i += 1)。
- 进入
感悟
AI的帮助总是令人意想不到,能通过检查我的代码,给我提出新的思路或修改建议,有的时候遇到一些棘手的问题,确实没办法通过自己的想法去解决,而且这些问题往往很难发现,而且耽误时间,通过AI的帮助,帮我节省了很多时间,而且豆包AI可以直接读取你写的代码,都不需要复制到聊天框再提问,这样大大节省了我的时间,有的时候还可以帮助我直接修改代码,并且帮助我解读,好处确实很多