给定一个整数 n(n≥1)和一个数字 k,返回将 n 写成 k 次方不同整数的所有可能方式。 例如,如果 n = 100 并且 k = 2:
100 = 1**2 + 3**2 + 4**2 + 5**2 + 7**2
= 6**2 + 8**2
= 10**2
或者如果 k = 3:
100 = 1**3 + 2**3 + 3**3 + 4**3
所以program(100,2)
返回类似于[(2, [1, 3, 4, 5, 7]), (2, [6, 8]), (2, [10])]
的东西,
而program(100,3)
返回[(3, [1, 2, 3, 4])]
。
只要输入n很小或k很大(>=3),一切都正常运作。 我的方法是首先获取所有整数的列表,其k次方为<= n。
def possible_powers(n,k):
arr,i = [],1
while i**k <= n:
arr.append(i)
i += 1
return arr
然后(这里犯了一个错误),我创建了这个列表的所有子集(作为列表):
def subsets(L):
subsets = [[]]
for i in L:
subsets += [subset+[i] for subset in subsets]
return subsets
最后,我循环遍历了所有这些子集,将每个元素提高到k次方并相加,只选择那些总和为n的子集。
def kth_power_sum(arr,k):
return sum([i**k for i in arr])
def solutions(n,k):
return [(k,i) for i in subsets(possible_powers(n,k)) if kth_power_sum(i,k) == n]
我知道问题出在子集创建上,但我不知道如何进行优化。比如说,如果我尝试solutions(1000,2),它会创建一个很大的集合,占用超过4GB的内存。我的猜测是筛选出一些子集,但除非我有一个非常高效的筛选方法,否则这并不能帮助太多。
非常感谢任何帮助。如果有什么不清楚的地方,或者我在发布此内容时犯了错误,请告诉我。
itertools
文档 中,你可以学习到如何懒惰地计算函数powerset
:每次只有一个子集被存储在内存中。 - Jorge Luis