比较容易实现的是递归的算法,就是最基本的DFS。
还有一种更优秀的数学构造法,值得学习一下。我们的目的是用n个数字构造一个逐位递增的k位数,现在尝试从小到大构造next combination.
以n=5,k=7为例子。最小的combination应该就是12345.那么我们会如何构造next comb呢?很显然我们会在最低位尝试加1,写出12346。再下一个,我们会写出12347.那么再下一个呢?显然最低位我们无法再增加1了,只好考虑十位数,发现可以在数字4上可以增加1也就是5;之后在最低位上,我们肯定会取最小的选择6,于是我们就写出了12356。
依次类推,假设当前的comb是12367,它的next comb是什么呢?个位数不能增加了;十位数也不能增加了(否则十位数是7的话,个位数就没法填写了);我们只有考虑在百位数上增加1.于是我们最终得到的是12456,
至此我们可以大致总结出做法。我们会从最低位开始看,尝试能否加1,如果那一位的数字已经到顶,我们就往前面找,知道能找到一位可以加1的地方comb[i];然后对于comb[i]后面的数字,我们会设置最小的组合,也就是依次令comb[j]=comb[j-1]+1。
一个最关键的分析,comb[i]的数字封顶是多少呢?简单的分析可以知道是i+1+n-k(注意我们这里的i是0-index)。理由是如果comb[i]取得再大的话,就没有足够的数字来填充i之后的位置了。