Given two integers n and k, return all possible combinations ofk 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], ]
思路一:用dfs,但是会报TLE
class Solution:
# @return a list of lists of integers
def combine(self, n, k):
def dfs(start, valuelist):
if self.count == k: res.append(valuelist); return
for i in range(start, n + 1):
self.count += 1
dfs(i + 1, valuelist + [i])
self.count -= 1
res = []; self.count = 0
dfs(1, [])
return res
思路二:用递归思想。在n个数中选k个,如果n大于k,那么可以分类讨论,如果选了n,那么就是在1到(n-1)中选(k-1)个,否则就是在1到(n-1)中选k个。递归终止的条件是k为1,这时候1到n都符合要求。
class Solution:
def combine(self, n, k):
if k == 1:
return [[i + 1] for i in range(n)]
res = []
if n > k:
res = [r + [n] for r in self.combine(n-1, k-1)] + self.combine(n-1, k)
else:
res = [r + [n] for r in self.combine(n-1, k-1)]
return res
解法三:用栈。这里要注意n-x+1 < k-1的意思是:
One combination has k
numbers, and currently we already have
l
numbers, so we need to find another k-l
numbers. Since we insert the numbers into stack in the ascending order, we want to make sure that there are enough larger numbers to be inserted. Fromx
to
n
, there are n-x+1
numbers that are larger than the numbers in the current stack. So ifn-x+1 < k-l
, it means that not enough larger numbers to be inserted, so we track back.
class Solution:
def combine(self, n, k):
ans = []
stack = []
x = 1
while True:
l = len(stack)
if l == k:
ans.append(stack[:])
if l == k or n-x+1 < k-l:
if not stack:
return ans
x = stack.pop() + 1
else:
stack.append(x)
x += 1