使用 Python 查詢 N 範圍內所有可能的唯一 K 大小組合


在許多程式設計場景中,我們經常遇到需要從給定的元素集中找到特定大小的所有可能組合的需求。這些組合可用於各種應用,例如生成排列、解決組合問題或探索資料的不同子集。在這篇博文中,我們將探討一種有效的方法,使用 Python 程式語言查詢直到給定數字 N 的所有大小為 K 的唯一組合。

理解問題

在我們深入研究解決方案之前,讓我們清楚地定義我們要解決的問題。給定從 1 到 N 的數字範圍和所需的組合大小 K,我們的目標是從給定範圍內生成 K 個數字的所有可能的唯一組合。

例如,假設我們有 N = 5 且 K = 3。預期輸出為:

[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]

方法和演算法

  • 建立一個空的結果列表來儲存組合。

result = []
  • 定義一個遞迴函式 backtrack,它接受以下引數:start 和 current_combination。

def backtrack(start, current_combination):
   # ... code for the recursive function ...
  • 如果 current_combination 的長度等於 K,則將其新增到結果列表中並返回。

if len(current_combination) == k:
   result.append(current_combination)
   return
  • 從 start 迭代到 N:

    • 將當前數字追加到 current_combination 中。

    • 遞迴呼叫 backtrack 函式,並將 start 加 1。

    • 從 current_combination 中刪除最後一個元素以回溯並探索其他可能性。

for i in range(start, n + 1):
    backtrack(i + 1, current_combination + [i])
  • 最初呼叫 backtrack 函式,並將 start 設定為 1,current_combination 設定為空。

backtrack(1, [])

處理無效輸入

為了確保我們解決方案的穩健性,我們可以新增一些輸入驗證檢查。例如,我們可以檢查給定的 N 值是否大於或等於 K。如果不是,我們可以引發異常或返回空列表,表明無法從小於 K 的範圍內形成大小為 K 的組合。

def combinations(n, k):
   if n < k:
      raise ValueError("Invalid input: N must be greater than or equal to K.")

   # ... 

最佳化演算法

當前的實現透過探索遞迴樹的所有分支來生成所有可能的組合。但是,如果所需的組合大小 K 相對較小,而範圍 N 則相對較大,我們可以透過修剪某些分支來最佳化演算法。例如,如果剩餘可供選擇的數字不足以形成大小為 K 的組合,我們可以停止探索該分支。

def combinations(n, k):
   # ... existing code ...

   def backtrack(start, current_combination):
      if len(current_combination) == k:
         result.append(current_combination)
         return

      # Optimization: Check if remaining numbers are enough for a valid combination
      if k - len(current_combination) > n - start + 1:
         return

      for i in range(start, n + 1):
         backtrack(i + 1, current_combination + [i])

   # ... 

這種最佳化減少了不必要的計算,並且可以顯著提高 N 和 K 值較大時演算法的效能。

無效輸入的示例輸出

讓我們考慮一個使用無效輸入的示例,以演示如何處理此類情況:

輸入

combinations(2, 4)
try:
   print(combinations(2, 4))
except ValueError as e:
   print(e)

輸出

Invalid input: N must be greater than or equal to K.

在這種情況下,我們引發 ValueError 以指示輸入無效,因為範圍 (2) 小於所需的組合大小 (4)。

在 Python 中實現解決方案

以下是解決方案的完整實現:

def combinations(n, k):
   result = []

   def backtrack(start, current_combination):
      if len(current_combination) == k:
         result.append(current_combination)
         return

      for i in range(start, n + 1):
         backtrack(i + 1, current_combination + [i])

   backtrack(1, [])
   return result

測試解決方案

讓我們使用一些示例輸入來測試解決方案:

示例

print(combinations(5, 3))

輸出

[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]

示例

print(combinations(4, 2))

輸出

[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

解釋

讓我們詳細分析第一個示例:

輸入:combinations(5, 3)

  • 最初,result 是一個空列表。

  • backtrack 函式被呼叫,其中 start = 1 且 current_combination = []。

  • 在迴圈的第一次迭代 (i = 1) 中,我們將 1 追加到 current_combination 並遞迴呼叫 backtrack(2, [1])。

  • 在迴圈的第一次迭代 (i = 2) 中,我們將 2 追加到 current_combination 並遞迴呼叫 backtrack(3, [1, 2])。

  • 由於 [1, 2] 的長度等於 3 (K),因此我們將其新增到結果中。

  • 回溯到上一個狀態,我們從 current_combination 中刪除最後一個元素以探索其他可能性 ([1])。

  • 在迴圈的第二次迭代 (i = 3) 中,我們將 3 追加到 current_combination 並遞迴呼叫 backtrack(4, [1, 3])。

  • 由於 [1, 3] 的長度等於 3 (K),因此我們將其新增到結果中。

  • 回溯到上一個狀態,我們從 current_combination 中刪除最後一個元素以探索其他可能性 ([1])。

  • 我們繼續此過程,直到生成所有可能的組合。

  • 最終結果為 [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]],它表示從數字 1 到 5 的所有大小為 3 的唯一組合。

結論

在這種方法中,我們利用回溯技術從給定的數字範圍內生成特定大小的所有可能的唯一組合。透過增量構建組合並在必要時回溯,我們系統地探索所有可能的解決方案。提供的程式碼片段演示了實現,並且示例輸出驗證瞭解決方案的正確性。

我們討論的方法涉及定義一個遞迴函式 backtrack,該函式增量構建有效的組合。透過遍歷數字範圍並遞迴呼叫 backtrack 函式,我們探索了所有可能的組合,並在遇到無效狀態時回溯。結果是滿足指定大小約束的唯一組合的完整列表。

為了驗證我們解決方案的正確性,我們使用示例輸入對其進行了測試。輸出表明程式碼成功生成了預期的組合,展示了已實現演算法的可靠性。

更新於:2023 年 8 月 16 日

583 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.