zoukankan      html  css  js  c++  java
  • leetcode-Combinations 复习复习排列组合

    Combinations

    题意:

      根据给定的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)]
            
    
  • 相关阅读:
    冲刺一(5)
    冲刺一(4)
    冲刺一(3)
    构建之法阅读笔记之二
    冲刺一(2)
    冲刺一(1)
    第9周总结
    热词顶会分析
    第8周总结
    构建之法阅读笔记之一
  • 原文地址:https://www.cnblogs.com/Blaxon/p/4786730.html
Copyright © 2011-2022 走看看