293.粮食分配的可能性计算
问题描述
粮食公司需要将nn吨粮食分配给若干分销商,每个分销商能够获得的粮食数量等于将nn除以分销商数量,向下取整。问题是,计算在可能的分销商数量中,分销商获得的不同粮食数量有多少种可能。
思路解析
- 整体目标:
给定总粮食吨数n,需要找出在不同分销商数量情况下,每个分销商所能获得粮食数量的不同可能性的种数。核心思路是通过遍历所有可能的分销商数量,计算出对应的每个分销商分得的粮食数量,再利用集合去重的特性,统计出不同分配数量的种类。 - 利用整数除法向下取整:
根据题目规则,每个分销商能够获得的粮食数量等于将n除以分销商数量,向下取整(通过//运算符实现)。例如,总共有 10 吨粮食,如果有 3 个分销商,那么每个分销商分得的粮食就是10 // 3 = 3吨(向下取整)。通过这样的计算方式,能得到不同分销商数量下对应的分配结果。 - 使用集合去重:
因为我们关心的是不同的分配数量有多少种,所以利用 Python 中集合(set)的特性,集合中的元素具有唯一性,将每次计算出来的分配数量添加到集合中,这样集合最终包含的元素个数就是不同分配方案的数量,也就是我们要求的结果。
解题步骤
- 初始化集合:
创建一个空集合
unique_allocations,用于存储不同的粮食分配方案(即每个分销商获得的粮食数量)。 - 遍历可能的分销商数量:
使用
for循环遍历从 1 到n的所有整数,这里的每个整数k代表一种可能的分销商数量情况。例如,当n = 5时,会依次考虑分销商数量为 1、2、3、4、5 这几种情况。 - 计算并添加分配方案到集合
在每次循环中,首先通过
n // k计算出当前分销商数量k下每个分销商能获得的粮食数量allocation(利用整数除法向下取整)。然后将这个计算得到的分配数量allocation添加到unique_allocations集合中。由于集合的去重特性,如果之前已经添加过相同的分配数量,这次添加操作不会重复添加该元素到集合里。 - 返回不同分配方案的数量:
循环结束后,集合
unique_allocations中已经包含了所有不同的分配数量,通过len(unique_allocations)获取集合中元素的个数,也就是不同分配方案的数量,并将这个数量作为函数的返回值返回,完成整个计算过程。
复杂度分析
- 时间复杂度: 函数里有个从 1 到
n的循环,循环执行n次,每次循环里做的操作花费时间基本固定,所以整体时间复杂度就是O(n)。 - 空间复杂度: 主要看存储不同分配方案的集合,最坏情况集合里元素个数和
n一样多,其他临时变量占空间不大,所以空间复杂度也是O(n)。
Code
def solution(n: int) -> int:
# 使用集合来存储不同的分配方案
unique_allocations = set()
# 遍历所有可能的分销商数量
for k in range(1, n + 1):
# 计算每个分销商数量下的分配方案
allocation = n // k
# 将分配方案加入集合
unique_allocations.add(allocation)
# 返回集合的大小,即不同的分配方案数量
return len(unique_allocations)
if __name__ == '__main__':
print(solution(5) == 3)
print(solution(7) == 4)
print(solution(10) == 5)