如何编写计算函数:
C(n,k)= 1 if k=0
0 if n<k
C(n-1,k-1)+C(n-1,k) otherwise
到目前为止,我有:
def choose(n,k):
if k==0:
return 1
elif n<k:
return 0
else:
答案 0 :(得分:2)
假设你的问题中缺少的操作数是减法运算符(感谢lejlot),这应该是答案:
def choose(n,k):
if k==0:
return 1
elif n<k:
return 0
else:
return choose(n-1, k-1) + choose(n-1, k)
请注意,在大多数Python系统中,max depth or recursion limit仅为1000.之后它将引发异常。您可能需要通过将此递归函数转换为迭代函数来解决此问题。
这是一个示例迭代函数,它使用堆栈来模拟递归,同时避免Python的最大递归限制:
def choose_iterative(n, k):
stack = []
stack.append((n, k))
combinations = 0
while len(stack):
n, k = stack.pop()
if k == 0:
combinations += 1
elif n<k:
combinations += 0 #or just replace this line with `pass`
else:
stack.append((n-1, k))
stack.append((n-1, k-1))
return combinations
答案 1 :(得分:0)
来自维基百科的解决方案(http://en.wikipedia.org/wiki/Binomial_coefficient)
def choose(n, k):
if k < 0 or k > n:
return 0
if k > n - k: # take advantage of symmetry
k = n - k
if k == 0 or n <= 1:
return 1
return choose(n-1, k) + choose(n-1, k-1)
答案 2 :(得分:0)
您正在尝试计算从n个元素中选择k的选项数量:
def choose(n,k):
if k == 0:
return 1 # there's only one option to choose zero items out of n
elif n < k:
return 0 # there's no way to choose k of n when k > n
else:
# The recursion: you can do either
# 1. choose the n-th element and then the rest k-1 out of n-1
# 2. or choose all the k elements out of n-1 (not choose the n-th element)
return choose(n-1, k-1) + choose(n-1, k)
答案 3 :(得分:0)
就像这样
def choose(n,k):
if k==0:
return 1
elif n<k:
return 0
else:
return choose(n-1,k-1)+choose(n-1,k)
修改强>
这是一种简单的方法,有效的方法可以看一下维基百科和spencerlyon2 answer
答案 4 :(得分:0)
到目前为止,所有答案均以指数时间 O(2n)
运行。但是,通过更改一行代码,可以在O(k)
中运行。
指数运行时间的原因是每次递归都会使用这行代码(see Ideone here)将问题分成重叠的子问题:
def choose(n, k):
...
return choose(n-1, k-1) + choose(n-1, k)
要了解为什么这么糟糕,请考虑choose(500, 2)
的例子。 500 choose 2
的数值为500*499/2
;但是,使用上面的递归需要250499
递归调用来计算它。显然这是过度的,因为只需要3次操作。
要将此改进为线性时间,您需要做的就是选择一个不会分裂为两个子问题的不同递归(wikipedia上有很多)。
例如,以下递归是等效的,但仅使用3
递归调用来计算choose(500,2)
(see Ideone here):
def choose(n,k):
...
return ((n + 1 - k)/k)*choose(n, k-1)
改进的原因是每次递归只有一个子问题,每次调用时k
减少1
。这意味着我们可以保证此递归仅需k + 1
次递归或O(k)
。这是改变单行代码的巨大改进!
如果您想更进一步,可以利用“n选择k”中的对称性来确保k <= n/2
(see Ideone here):
def choose(n,k):
...
k = k if k <= n/2 else n - k # if k > n/2 it's equivalent to k - n
return ((n + 1 - k)/k)*choose(n, k-1)