python三个数求和_求和为三个最小数的排列

诀窍是只生成可能需要的组合,并将它们存储在堆中。你拿出的每一个都是你还没见过的最小的。事实上,这个组合已经被拔出,这告诉你还有一些新的组合,它们可能也很小。在

有关如何使用堆,请参见https://docs.python.org/2/library/heapq.html。我们还需要生成组合的代码。然后,这里是为任何列表列表获取第一个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))]

selectors.append(ListSelector(lists, new_indexes))

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):

value, sel = heapq.heappop(upcoming)

yield sel

for next_sel in sel.next_selectors():

heapq.heappush(upcoming, (next_sel.value(), next_sel))

# 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内部的值并为新的列表增量计算值等技巧,可以使这一方法更加有效。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值