递归是基于一个简单的观察,为此我将给出一个组合论证,说明为什么它是正确的,而不是通过公式进行数学证明。
每当您从 中选择k
元素时n
,都有两种情况:
- 你选择元素
#n
- 你不选择元素
#n
由于这些事件是互斥的,因此组合的总数由选择时的组合数量#n
和不选择时的组合数量给出#n
。
选择元素#n
由于我们已经选择了一个元素,我们只需要选择另一个k-1
元素。此外,由于我们已经决定了一个元素——是否包含它——我们只需要考虑剩余的n-1
元素。
因此,选择元素的组合数量#n
由下式给出
subset(n - 1, k - 1)
不选择元素#n
仍然有k
元素可供选择,但由于我们已经决定了 element #n
,因此只有n - 1
元素可供选择。因此:
subset(n - 1, k)
基本情况
递归使用了这样一个事实,即我们通常可以区分两种情况,即元素n
是该解决方案的一部分的解决方案,以及元素不是该解决方案的一部分的解决方案。
然而,这样的区别并不总是可以做出:
- 选择所有元素时(对应
n == k
于下面代码中的大小写)
- 或者根本不选择任何元素时(对应
k == 0
于下面代码中的大小写)
在这些情况下,只有一种解决方案,因此
if k == 0:
return 1
if n == k:
return 1
确保它有效
要做到这一点,我们需要说服自己(或证明)基本情况总是在某个时候被击中。
让我们假设,n < k
在某个时候。由于根据我们的假设,n
最初大于或等于k
,因此一定有某个点n = k
,因为n
和k
一致减少或仅n
减少 1,即它遵循
这意味着,必须有一个要求subset(n - 1, k)
它发生,n
低于k
。但是,这是不可能的,因为我们有一个n = k
返回常量的基本情况1
。
我们得出结论,要么n
在某个点上减少,要么n = k
一致地减少,精确k
到这样k = 0
。
因此,基本情况有效。