77. 组合

77. 组合

题意

给定两个整数 nk,返回 1 ... n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

解题思路

class Solution(object):
   def combine(self, n, k):
       """
      :type n: int
      :type k: int
      :rtype: List[List[int]]
      """

       def backtracking(start, end, path):
           if len(path) >= k:
               res.append(path)
               return

           for i in range(start, end + 1):
               backtracking(i + 1, end, path + [i])

       if not k or not n:
           return []
       res = []
       backtracking(1, n, [])
       return res

超时了,于是我想到了之前一种比较巧妙的迭代方法,可以获取到第index的内容,如下:

class Solution(object):
   def combine(self, n, k):
       """
      :type n: int
      :type k: int
      :rtype: List[List[int]]
      """
       res = [[]]
       for i in range(k):
           temp = []
           for r in res:
               for i in range(1 if not r else r[-1]+1, n+1):
                   temp.append(r+[i])
           res = temp[:]
       return res

实现

不像排列,任意位置进行交换,组合只能是按照顺序的。

  1. 使用原生的combinations来实现;

  2. 和我之前的做法的区别在于不是加入到数组后再判断它们的长度,而是通过记录当前数组剩余的空间长度;

from itertools import combinations

class Solution:
   def combine(self, n, k):
       return list(combinations(range(1, n+1), k))

   def combine(self, n, k):
       """
      :type n: int
      :type k: int
      :rtype: List[List[int]]
      """
       res = []
       
       def helper(depth, path, k):
           if not k:
               res.append(path)
               return
           
           for i in range(depth, n+1):
               helper(i+1, path+[i], k-1)
       
       if not n:
           return []
       
       helper(1, [], k)
       return res
     
  def combine(self, n, k):
       """
      :type n: int
      :type k: int
      :rtype: List[List[int]]
      """
       def backtracking(start, end, path):
           if len(path) >= k:
               res.append(path)
               return

           for i in range(start, end + 1):
            # 和最后一个值和当前值进行比较,保证有序
               # 如果没有加上判断的话,那么就会出现[4, 3], [4, 4]没有顺序并且重复的情况,这是因为如果是start+1的话,每次在循环的过程中,递归的深度是一样的,i 在循环的时候就有可能运行到比 start 还要大,本来就是通过 i 的值来控制有序;
               if path and path[-1] >= i:
                   continue
               backtracking(start + 1, end, path + [i])
       
       if not k or not n:
           return []
       res = []
       backtracking(1, n, [])
       return res
posted @ 2017-08-31 16:30  banananana  阅读(159)  评论(0)    收藏  举报