标签:
题意:
根据给定的n和k,生成从1到n范围内长度为k的排列组合
示例:
n=4 k=2
[[1, 2],
[1, 3],
[1, 4],
[2, 1],
[2, 3],
[2, 4],
[3, 1],
[3, 2],
[3, 4],
[4, 1],
[4, 2],
[4, 3]]
解题:
正常情况下我们通常想到的都是通过使用递归,以枚举的形式来生成组合。先从给定的范围中拿一个数出来,把它同剩下的每一个数进行组合,然后再在每个组合上对不存在于组合的每个数进行合并,这样依次的进行合并操作,最终生成我们需要的排列。
但我发现,使用这个方法在leetcode上提交是会提示超时的。后来我发现其实我们可以使用排列组合中的公式:
C(n,k) = C(n-1,k) + C(n-1, k-1)
这个公式直观的解释是,求范围n中长度为k的排列组合个数可以换算成求范围n-1中长度为k的排列组合个数与范围n-1中长度为k-1的排列组合个数之和。
这么听起来,不仅绕口,而且感觉貌似这个公式和我们要达到的目的貌似并没有什么用。。其实我们换一种角度就很容易理解了。
我们要求范围n长度为k的排列组合,如果我们可以求得范围n-1长度k的排列组合,那么我们还需要求出包含数字n的长度为k的排列组合,然而求范围n-1长度为k-1
的排列组合正好就是为了并上数字n,这样获得的排列组合正好是求出C(n-1,k)所差得哪些排列。因此我们的代码可以写成:
class Solution(object): def combine(self, n, k): """ :type n: int :type k: int :rtype: List[List[int]] """ if n == k: return [range(1, n+1)] if k == 1: return [[item] for item in range(1, n+1)] ret = self.combine(n-1, k) other = self.combine(n-1, k-1) for item in other: item.append(n) ret += other return ret
如果要想我们的code 显得更加的pythonic,我们还可以这样写:
class Solution(object): def combine(self, n, k): """ :type n: int :type k: int :rtype: List[List[int]] """ if n == k: return [range(1, n+1)] if k == 1: return [[item] for item in range(1, n+1)] return self.combine(n-1, k) + [item + [n] for item in self.combine(n-1, k-1)]
leetcode-Combinations 复习复习排列组合
标签:
原文地址:http://www.cnblogs.com/Blaxon/p/4786730.html