描述:
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 即 排列组合的问题. 对于例子来说,就是C4, 2, 从4个里面取出两个来.
之前有做过全排列的问题和求所有子集的问题. 见: http://www.cnblogs.com/missmzt/p/5527382.html
这里的解决方法都是通过回溯法来解决. 个人对于回溯法还不是很熟练,主要在于回溯时条件函数的设计吧.
例如之前的 全排列问题是 通过一个标记数组, 标记第i个数是否放入结果集合中.
对于组合问题, 当回溯判断 集合的长度达到k时, 这时应该返回上一层, 开始回溯. 在回溯的过程中,我们设定开始的数和结束的数.
代码如下:
1 class Solution(object): 2 def combine(self, n, k): 3 """ 4 :type n: int 5 :type k: int 6 :rtype: List[List[int]] 7 """ 8 9 res = [] 10 fin = [] 11 self.helper(res, 0, n, k, fin) 12 return fin 13 14 def helper(self, res, s, n, k, fin): 15 if len(res) == k: 16 fin.append(list(res)) # python的深拷贝与浅拷贝 17 return 18 for i in range(s, n): 19 res.append(i+1) 20 self.helper(res, i+1, n, k, fin) 21 res.pop()
运行结果: [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
求子集的代码如下:
1 #!/usr/bin/env python 2 #coding=utf-8 3 4 def ziji(cur, n, a, b): 5 if cur == n: 6 b = [] 7 for i in range (0, n): 8 if a[i] == 1: 9 b.append(i+1) 10 print b 11 return 12 13 a[cur] = 1 14 ziji(cur+1, n, a, b) 15 a[cur] = 0 16 ziji(cur+1, n, a, b) 17 a = [0]*4 18 ziji(0, 4, a, []);