1. 程式人生 > 實用技巧 >LeetCode 77. 組合 | Python

LeetCode 77. 組合 | Python

77. 組合


題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/combinations

題目


給定兩個整數 n 和 k,返回 1 ... n 中所有可能的 k 個數的組合。

示例:

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

解題思路


思路:組合數

先審題,題目要求給定 n,返回 1...n 中所有可能的 k 個數組合。我們可以發現,這其實就是高中數學概念上的組合數問題。

組合的定義: 從 n 個不同元素中,任取 m($m \leq n$)個不同元素組成一組,稱為組合。

組合數的定義: 從 n 個不同元素中,任取 m($m \leq n$)個不同元素的所有組合的個數,叫做組合數,記為 $C_{n}^{m}$。

組合數有這樣一個性質:

$$C_{n+1}^{m} = C_{n}^{m} + C_{n}^{m-1}$$

這裡我們令 n' = n+1,那麼上面的式子則會變成:

$$C_{n'}^{m} = C_{n'-1}^{m} + C_{n'-1}^{m-1}$$

其實也就等同於:

$$C_{n}^{m} = C_{n-1}^{m} + C_{n-1}^{m-1}$$

這裡我們可以這樣去理解上面的式子。假設現在從 n 個元素選 m 個元素,也就是 $C_{n}^{m}$。這裡,我們先選擇一個需要特殊考慮的元素,那麼就會有以下兩種情況:

  • 當選取的元素中不含這個特殊元素,那麼就需要在剩餘的 n-1 個元素中選出 m 個元素,也就是 $C_{n-1}^{m}$;
  • 當選取的元素中含有這個特殊元素,那麼就需要從剩餘的 n-1 個元素中選出 m-1 個元素,也就是 $C_{n-1}^{m-1}$ 。

最終,將兩種情況結合起來,從 n 個元素選 m 個元素的情況。

那麼就按照這個思路,進行實現,這裡每次選取特殊元素為可選元素集合中最小的元素。

具體程式碼實現如下(遞迴方法)。

from typing import List

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        ans = []
        tmp = []

        def helper(special, n, k):
            # k 個元素選擇完成,新增到返回列表中
            if k == 0:
	            # 這裡注意新增的是副本
	            # 具體原因,建議自行除錯檢視
                ans.append(tmp[::])
                return
            # 表示剩餘元素不夠選擇 k 個元素,直接返回
            if k > n:
                return

            tmp.append(special)
            helper(special+1, n-1, k-1)
            tmp.pop()
            helper(special+1, n-1, k)

        helper(1, n, k)

        return ans

# n = 4
# k = 2
# solution = Solution()
# ans = solution.combine(n, k)
# print(ans)

歡迎關注


公眾號 【書所集錄