訣竅是只生成可能需要的組合,並將它們儲存在堆中。你拿出的每乙個都是你還沒見過的最小的。事實上,這個組合已經被拔出,這告訴你還有一些新的組合,它們可能也很小。在
有關如何使用堆,請參見我們還需要生成組合的**。然後,這裡是為任何列表列表獲取第乙個n組合的工作**:import heapq
# helper class for storing combinations.
class listselector:
def __init__(self, lists, indexes):
self.lists = lists
self.indexes = indexes
def value(self):
answer = 0
for i in range(0, len(self.lists)):
answer = answer + self.lists[i][self.indexes[i]]
return answer
def values(self):
return [self.lists[i][self.indexes[i]] for i in range(0, len(self.lists))]
# these are the next combinations. we are willing to increment any
# leading 0, or the first non-zero value. this will provide one and
# only one path to each possible combination.
def next_selectors(self):
lists = self.lists
indexes = self.indexes
selectors =
for i in range(0, len(lists)):
if len(lists[i]) <= indexes[i] + 1:
if 0 == indexes[i]:
continue
else:
break
new_indexes = [
indexes[j] + (0 if j != i else 1)
for j in range(0, len(lists))]
if 0 < indexes[i]:
break
return selectors
# this will just return an iterator over all combinations, from smallest
# to largest. it does not generate them until needed.
def combinations(lists):
sel = listselector(lists, [0 for _ in range(len(lists))])
upcoming = [(sel.value(), sel)]
while len(upcoming):
yield sel
for next_sel in sel.next_selectors():
# this just gets the first n of them. (it will return less if less.)
def smallest_n_combinations(n, lists):
i = 0
for sel in combinations(lists):
yield sel
i = i + 1
if i == n:
break
# example usage
lists = [
[1, 2, 5],
[2, 3, 4],
[1]]
for sel in smallest_n_combinations(3, lists):
print(sel.value(), sel.values(), sel.indexes)
(對於一長串的列表,使用諸如快取listselector內部的值並為新的列表增量計算值等技巧,可以使這一方法更加有效。)
三個數和為零
給出乙個長度為n的無序陣列,陣列中的元素為整數,有正有負包括0,並互不相等。從中找出所有和 0的3個數的組合。如果沒有這樣的組合,輸出no solution。如果有多個,按照3個數中最小的數從小到大排序,如果最小的數相等則按照第二小的數排序。input 第1行,1個數n,n為陣列的長度 0 n 10...
三個數的和為0
給出乙個長度為n的無序陣列,陣列中的元素為整數,有正有負包括0,並互不相等。從中找出所有和 0的3個數的組合。如果沒有這樣的組合,輸出no solution。如果有多個,按照3個數中最小的數從小到大排序,如果最小的數相等則按照第二小的數排序。input 第1行,1個數n,n為陣列的長度 0 n 10...
三個數之和
b 問題 b 給定乙個由n個整數組成的陣列s,是否存在s中的三個數a,b,c使得 a b c 0?找出所有的不重複的和為0的三元組。注意 1.三元組的整數按照公升序排列 a0 c向前移一位,減小和 還要注意的是去掉重複的解,保證a和b都和上次的不同即可。如下 public class solutio...