回溯法經典練習:組合總和的深度解析與實戰

回溯法經典練習:組合總和的深度解析與實戰

引言

在算法世界里,回溯法(Backtracking)是解決 組合、排列、子集 等問題的神器。而 “組合總和”(Combination Sum) 問題,更是回溯算法中的經典代表,幾乎是算法面試中的常客。

今天,我就帶大家從 直覺理解代碼實戰,深入解析回溯法如何求解 組合總和,并給出代碼詳解,帶你徹底吃透這個問題!


1. 題目解析

🔹 題目描述

給定一個 無重復元素 的正整數數組 candidates,以及一個目標值 target,找到所有可以使數字和為 target唯一組合

要求:

  • 同一個數字可以被無限次使用,但組合的順序不影響結果(即 {2,2,3}{3,2,2} 視為相同組合)。
  • 結果集不能包含重復的組合。

示例:

輸入: candidates = [2,3,6,7], target = 7
輸出: [[2,2,3],[7]]
解釋: 2+2+3 = 7, 7 = 7,因此答案是 [[2,2,3],[7]]

2. 直覺思考

這個問題的求解方式,可以類比 爬樓梯

  • 每次選擇一個數(例如 2 或 3 或 6 或 7)。
  • 判斷當前累加和是否等于目標值 target
  • 如果超過 target,則不合法,剪枝回溯。
  • 如果剛好等于 target,就加入結果集。

看到 “所有組合”“無序”“可以重復選擇” 這些關鍵詞,回溯法就是最佳選擇!


3. 回溯算法核心框架

回溯法的核心思路是 “遞歸 + 回溯 + 剪枝”,通常分為以下幾個步驟:

  1. 終止條件:當當前路徑的總和等于 target,將其加入結果集。
  2. 選擇操作:從 candidates 里選擇一個數,嘗試加入當前路徑。
  3. 遞歸調用:累加該數后,繼續探索下一個可能的組合。
  4. 回溯撤銷選擇:探索完該路徑后,撤銷最后一個選擇,回溯到上一步繼續嘗試其他數。

回溯法的框架:

def backtrack(路徑, 選擇列表):if 滿足結束條件:記錄結果returnfor 選擇 in 選擇列表:做選擇backtrack(路徑, 選擇列表)  # 遞歸撤銷選擇  # 回溯

4. 代碼實戰

🔹 Python 代碼

from typing import Listdef combinationSum(candidates: List[int], target: int) -> List[List[int]]:res = []  # 結果集def backtrack(start, path, total):# 遞歸終止條件:找到一個滿足條件的組合if total == target:res.append(path[:])  # 注意要拷貝 pathreturn# 遍歷候選數組for i in range(start, len(candidates)):num = candidates[i]# 剪枝:如果 total + num 超過 target,則不再繼續if total + num > target:continue# 選擇當前數字,遞歸path.append(num)backtrack(i, path, total + num)  # 這里 `i` 而不是 `i+1`,因為允許重復選擇path.pop()  # 回溯,撤銷選擇# 從索引 0 開始搜索backtrack(0, [], 0)return res

5. 代碼詳解

🔸 遞歸邏輯

  • backtrack(start, path, total)
    • start:控制遞歸深度,避免重復選擇前面的數。
    • path:記錄當前的組合路徑。
    • total:當前路徑的累加和。

🔸 關鍵點

  1. 循環遍歷 candidates
    • start 位置開始,避免重復使用已選過的數。
    • 允許重復選擇 candidates[i],所以 backtrack(i, ...) 而不是 backtrack(i+1, ...)
  2. 剪枝優化
    • total + num > target 時,提前終止遞歸,避免不必要的計算。
  3. 回溯撤銷選擇
    • 遞歸完一個分支后,撤銷 path.append(num) 的選擇,繼續嘗試其他數。

6. 測試代碼

candidates = [2, 3, 6, 7]
target = 7
print(combinationSum(candidates, target))

輸出結果:

[[2, 2, 3], [7]]

7. 復雜度分析

假設 candidates 長度為 N,目標值 target

  • 最壞情況下,回溯的搜索樹是一個 N 叉樹,高度為 target/min(candidates)
  • 時間復雜度 近似為 O(2^N)(指數級)。
  • 空間復雜度 近似 O(N)(遞歸棧空間 + 結果集存儲)。

8. 進階優化

🔹 剪枝優化

在搜索前 先對 candidates 排序,一旦發現 total + num > target,就可以提前停止當前分支,減少不必要的遞歸:

candidates.sort()  # 先排序,提高剪枝效率

🔹 記憶化搜索

如果 candidates 很多,可以用 字典(哈希表) 存儲 target 計算結果,避免重復計算。


9. 結語

回溯法是組合問題的利器,而 “組合總和” 這個問題,是典型的 遞歸 + 剪枝 題目,掌握它,你就能輕松應對類似的算法題。

🔹 復習總結

  1. 回溯三步走:選擇 -> 遞歸 -> 回溯
  2. 通過 start 參數避免重復i 位置不變以允許重復選取數字。
  3. 剪枝優化:如果 total + num > target,則立即跳過
  4. 理解遞歸樹的結構,有助于更好地 Debug

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72940.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72940.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72940.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

傳感器研習社:Swift Navigation與意法半導體(STMicroelectronics)合作 共同推出端到端GNSS汽車自動駕駛解決方案

自動駕駛系統單純依賴感知傳感器進行定位在遇到惡劣天氣或缺乏車道標線的道路場景時很容易失效。此外,由于激光雷達(LiDAR)、視覺等傳感器的成本高昂以及將眾多不同組件整合為統一系統的復雜性,都可能增加產品研發成本或延遲產品上…

【人工智能】Ollama 的 API 操作指南:打造個性化大模型服務

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著人工智能技術的飛速發展,大型語言模型(LLM)在自然語言處理領域的應用日益廣泛。然而,傳統的云端模型服務往往面臨數據隱私、成本高…

Linux關機重啟二三事

、、 1概述 故障是高可用組最常接觸的場景,其中包含了進程故障,網絡故障、系統故障,硬件故障。掉電、關機和重啟作為其中最常見的系統故障,具體的細節還是有些許差異的。本文將從操作系統與主板的行為講解三者之間的聯系與區別。…

算法1--兩束求和

題目描述 解題思路 先說一種很容易想到的暴力解法 暴力解法的思路很簡單,就是遍歷數組,對于每一個元素,都去遍歷數組中剩下的元素,判斷是否有兩個元素的和等于目標值,如果有,就返回這兩個元素的下標。 c…

在Fedora-Workstation-Live-x86_64-41-1.4中使用最新版本firefox和騰訊翻譯插件讓英文網頁顯示中文翻譯

在Fedora-Workstation-Live-x86_64-41-1.4中使用最新版本firefox和騰訊翻譯插件讓英文網頁顯示中文翻譯 應用——系統工具——終端 suozhangfedora:~$ rpm -aq | grep firefox firefox-131.0.2-1.fc41.x86_64 firefox-langpacks-131.0.2-1.fc41.x86_64 fedora41系統自身安裝有f…

android 接入google 登錄

在 Android 應用中接入 Google 登錄功能,可讓用戶使用他們的 Google 賬號快速登錄應用。以下是詳細的接入步驟和示例代碼: 步驟 1:創建 Google API 項目 訪問 Google API 控制臺,并使用你的 Google 賬號登錄。點擊 “選擇項目”,然后點擊 “新建項目”,按照提示填寫項目…

Redis緩存與數據庫 數據一致性保障

為什么要保證數據一致性 只要使用redis做緩存,就必然存在緩存和DB數據一致性問題。若數據不一致,則業務應用從緩存讀取的數據就不是最新數據,可能導致嚴重錯誤。比如將商品的庫存緩存在Redis,若庫存數量不對,則下單時…

19.哈希表的實現

1.哈希的概念 哈希(hash)?稱散列,是?種組織數據的?式。從譯名來看,有散亂排列的意思。本質就是通過哈希函數把關鍵字Key跟存儲位置建??個映射關系,查找時通過這個哈希函數計算出Key存儲的位置,進?快速查找。 1.2.直接定址法…

IoTDB TTL不生效

問題 時序數據庫 IoTDB 1.3.0 版本數據庫的 TTL 設置為兩天,show databases details 看到設置也是正確的,怎么還是可以查到好幾天前的數據?因為有很多不活躍的測點,所以專門設置了兩天過期,有什么辦法可以自動清理呢&…

【C++基礎】Lambda 函數 基礎知識講解學習及難點解析

一、引入 在 C 中,我們通常使用函數來完成特定的功能。但有時候,我們需要在一個函數內部定義一個小型的功能塊,這時如果單獨寫一個函數會顯得繁瑣。C11 引入了 Lambda 函數,它是一種匿名函數,可以在需要的地方直接定義…

OpenCV 基礎模塊 Python 版

OpenCV 基礎模塊權威指南(Python 版) 一、模塊全景圖 plaintext OpenCV 架構 (v4.x) ├─ 核心層 │ ├─ core:基礎數據結構與操作(Mat/Scalar/Point) │ └─ imgproc:圖像處理流水線(濾…

iStoreOS軟路由對硬盤格式化分區(轉化ext4)

一、為什么要格式化分區? 格式化硬盤分區是軟路由安裝或配置過程中的重要步驟,主要用于清除舊數據、優化文件系統、確保系統穩定性和兼容性。 二、通過iStoreOS硬盤格式化步驟 使用場景:Docker遷移到外置移動硬盤為例,考慮兼容現…

打造用戶認證系統,構筑信息安全防線

在當今的數字化時代,信息安全和用戶隱私保護變得越來越重要。用戶身份認證是確保信息安全的第一道防線。通過驗證用戶身份,可以防止未經授權的訪問和數據泄露。它有助于保護用戶的個人信息、賬戶資金和其他敏感數據。此外,用戶身份認證還可以…

北京南文觀點:品牌如何搶占AI 認知的 “黃金節點“

在算法主導的信息洪流中,品牌正在經歷一場隱蔽的認知權爭奪戰,當用戶向ChatGPT咨詢"哪家新能源車企技術最可靠"時,AI調取的知識圖譜數據源將直接決定品牌認知排序。南文樂園科技文化(北京)有限公司&#xff…

音視頻系列——Websockets接口封裝為Http接口

模型服務示例:實時語音轉文本服務 本示例展示一個支持雙協議(WebSocket流式接口HTTP同步接口)的語音轉文本模型服務,并提供將WebSocket接口封裝為HTTP接口的代碼實現。 一、服務架構設計 #mermaid-svg-nw0dMZ4uKfS4vGZR {font-fa…

Axure項目實戰:智慧城市APP(一)(動態面板、拖動效果)

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝! 課程主題:智慧城市APP便民服務平臺 主要內容:完整智慧APP原型設計 應用場景:各類政務型、B端APP均可參考 案例展示:&…

MySQL 入門大全:數據類型

🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/literature?__c1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,…

Java 記憶鏈表,LinkedList 的升級版

文章目錄 記憶鏈表 MemoryLinkedList實戰源代碼 眾所周知,ArrayList 和 LinkedList 是 Java 集合中兩個基本的數據結構,對應數據結構理論中的數組和鏈表。但在這兩個數據結構,開發者們通常使用 ArrayList,而不使用 LinkedList。JD…

《白帽子講 Web 安全》之開發語言安全深度解讀

目錄 引言 1.PHP 安全 1.1變量覆蓋 1.2空字節問題 1.3弱類型 1.4反序列化 1.5安全配置 2Java 安全 2.1Security Manager 2.2反射 2.3反序列化 3Python 安全 3.1反序列化 3.2代碼保護 4.JavaScript 安全 4.1第三方 JavaScript 資源 4.2JavaScript 框架 5.Node.…

鴻蒙HarmonyOS NEXT應用崩潰分析及修復

鴻蒙HarmonyOS NEXT應用崩潰分析及修復 如何保證應用的健壯性,其中一個指標就是看崩潰率,如何降低崩潰率,就需要知道存在哪些崩潰,然后對癥下藥,解決崩潰。那么鴻蒙應用中存在哪些崩潰類型呢?又改如何解決…