[英]Shortest subset for given sum and fastest solution in Python
這是“給定和問題”的一個變體,我嘗試用Python編寫一個解決方案,該解決方案將在O(log n)
時間內解決。 對於給定的自然數N
(equal or larger than 1)
找到項p
1..n
的最短計數,這些和使N
,並且p
項是以下迭代的乘積:
p
i
值是p
i-1
* 2
或p
i-1
+ 1
從p
1
開始,恰好是1
因此:
p
2
始終為2,但p
3
可以為3或4
對於輸入N = 18
,候選集為:[1、2、4、5、6],[1、2、3、4、8],[1、2、4、5、6],[1, 2,3,4,8]
answer is 5
。
到目前為止,這是我編寫的代碼,但運行緩慢,並且凍結在中等“大”(N> = 1000)值上:
possible = None
def solution(N):
global possible
possible = list()
tea(1, [1], N)
sizes = [len(p) for p in possible]
return min(sizes)
pass
def tea(n, l, target):
global possible
if (sum(l) > target):
return
elif (sum(l) == target):
possible.append(l)
i = n * 2
tea(i, l + [i], target)
i = n + 1
tea(i, l + [i], target)
print solution(18)
# should print 5
print solution(220)
# should print 11
print solution(221)
# no such solution? print -1
如何以更有效的方式解決它?
最快的解決方案是最關鍵的,但是也需要更多的Python代碼。
使用廣度優先搜索來減少浪費的精力。 下面的代碼可以進一步優化。
def solution(n):
q = [(1,)]
visited = set()
for seq in q:
s = sum(seq)
if s == n:
return seq
elif s > n:
continue
key = (seq[-1], s)
if key in visited:
continue
visited.add(key)
q.append(seq + (seq[-1] * 2,))
q.append(seq + (seq[-1] + 1,))
return None
您正在尋找最短的解決方案,因此,如果找到了解決方案,則無需尋找更長的解決方案。
您可以更改代碼,以使它不會再以這種方式找到解決方案:
(注意條件是否添加)
def tea(n, l, target):
global possible
if (sum(l) > target):
return
elif (sum(l) == target):
possible.append(l)
# we want to keep looking for new solutions only if l is shorter!
if possible and (len(l) >= max(len(i) for i in possible)):
return
i = n * 2
tea(i, l + [i], target)
i = n + 1
tea(i, l + [i], target)
另外,似乎您希望函數在沒有解決方案時返回-1
,目前,您的代碼在這種情況下會引發錯誤,我將solution()
函數更改為:
possible = []
def solution(N):
global possible
tea(1, [1], N)
sizes = [len(p) for p in possible] # you can use: size = map(len,possible) instead
if sizes:
return min(sizes)
return -1
至於您的“更多pythonic代碼”,我會這樣寫:
def solution(N):
possibles =[]
tea(1, [1], N, possibles)
if not possibles:
return -1
else:
return min(map(len,possibles))
def tea(n, l, target, possibles): # maybe a better name then "tea"
if (sum(l) > target):
return
elif (sum(l) == target):
possibles.append(l)
return
if possibles and (len(l) >= max(len(i) for i in possibles)):
return
tea(n * 2, l + [n * 2], target, possibles)
tea(n + 1, l + [n + 1], target, possibles)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.