递归是基于一个简单的观察,为此我将给出一个组合论证,说明为什么它是正确的,而不是通过公式进行数学证明。
每当您从 中选择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。
因此,基本情况有效。