216. 組合總和 III 回溯

目錄

問題描述

解決思路

關鍵點

代碼實現

代碼解析

1. 初始化結果和路徑

2. 深度優先搜索(DFS)

3. 遍歷候選數字

4. 遞歸與回溯

示例分析

復雜度與優化

回溯算法三部曲

1. 路徑選擇:記錄當前路徑

2. 遞歸探索:進入下一層決策

3. 撤銷選擇:回溯到上一層

?代碼框架模板

關鍵點解析

總結


問題描述

我們需要找出所有由?k?個不同數字組成的組合,這些數字的范圍是?1 到 9,且它們的和等于?n。組合中的數字不能重復使用,且結果不能包含重復的組合。例如,當?k=3, n=7?時,唯一有效的組合是?[1,2,4]

解決思路

這個問題可以通過回溯算法解決。核心思想是遞歸地嘗試每一個可能的數字,逐步構建符合條件的組合,并通過剪枝優化減少無效搜索。

關鍵點
  1. 數字范圍固定:所有數字只能在?1-9?中選擇。

  2. 組合唯一性:每個組合中的數字必須嚴格遞增,避免重復(如?[1,2,4]?和?[2,1,4]?被視為同一組合)。

  3. 剪枝優化:在遞歸過程中,提前終止不可能滿足條件的分支,大幅提高效率。

代碼實現

var combinationSum3 = function (k, n) {const result = [];const path = [];const dfs = (start, sum) => {// 終止條件:路徑長度等于k且和等于nif (path.length === k && sum === n) {result.push([...path]);return;}// 遍歷候選數字for (let i = start; i <= 9; i++) {// 剪枝1:剩余數字不夠組成k個數if (path.length + (9 - i + 1) < k) break; // 剪枝2:當前和超過nif (sum + i > n) break; path.push(i);dfs(i + 1, sum + i); // 遞歸下一層,起始位置為i+1path.pop();          // 回溯,撤銷選擇}};dfs(1, 0); // 從數字1開始,初始和為0return result;
};

代碼解析

1. 初始化結果和路徑
  • result:存儲所有符合條件的組合。

  • path:記錄當前遞歸路徑中的數字。

2. 深度優先搜索(DFS)
  • 參數start?表示當前遞歸的起始數字,sum?表示路徑中數字的當前和。

  • 終止條件:當路徑長度等于?k?且和等于?n?時,將當前路徑加入結果列表。

3. 遍歷候選數字
  • 循環范圍:從?start?到?9,確保數字遞增,避免重復組合。

  • 剪枝1path.length + (9 - i + 1) < k
    如果當前已選數字數量加上剩余可用數字數量不足?k,說明無法組成有效組合,直接終止循環。
    例如:k=3,當前已選1個數字,剩余可用數字是?8?和?9(共2個),顯然不夠選2個。

  • 剪枝2sum + i > n
    如果當前路徑和加上?i?已經超過?n,后續更大的數字只會讓和更大,無需繼續搜索。

4. 遞歸與回溯
  • 選擇數字:將?i?加入路徑,遞歸調用?dfs?處理下一個數字。

  • 撤銷選擇:遞歸返回后,將?i?從路徑中移除,嘗試其他可能的數字。

示例分析

以?k=3, n=7?為例:

  1. 初始調用dfs(1, 0)

  2. 第一層循環i=1,路徑為?[1],和為1。

  3. 第二層循環i=2(起始為2),路徑為?[1,2],和為3。

  4. 第三層循環i=4(起始為3),路徑為?[1,2,4],和為7,滿足條件,加入結果。

  5. 回溯:遞歸返回,嘗試其他數字,但均無法滿足條件,最終結果唯一。


復雜度與優化

  • 時間復雜度:最壞情況為?O(9! / (k!(9-k)!)),即組合數的時間。

  • 空間復雜度:遞歸棧深度為?k,空間復雜度為?O(k)

通過剪枝,實際運行時間遠低于理論最壞情況,因為無效分支被提前終止。


回溯算法三部曲

回溯算法是解決組合、排列、子集等問題的經典方法。它的核心思想是遞歸地嘗試所有可能的選擇,并通過“撤銷選擇”回到之前的狀態,從而窮舉所有解。其實現過程可以總結為以下三個關鍵步驟:


1. 路徑選擇:記錄當前路徑

在每一步遞歸中,將當前的選擇加入路徑(通常是一個數組),表示“當前正在嘗試這個選擇”。
對應代碼path.push(i)
作用:保存當前遞歸層的選擇,用于后續判斷是否滿足條件。
示例:在組合問題中,選擇數字?i?加入?path,表示嘗試將?i?作為組合的一部分。


2. 遞歸探索:進入下一層決策

基于當前路徑,遞歸調用函數,處理下一個選擇(比如下一個數字或位置)。
對應代碼dfs(i + 1, sum + i)
作用:進入下一層遞歸,繼續嘗試剩余的選擇。
示例:在組合問題中,遞歸時從?i+1?開始,確保數字不重復且遞增,避免重復組合。


3. 撤銷選擇:回溯到上一層

當遞歸返回后(即完成當前分支的探索),將最后加入路徑的元素移除,回到上一層狀態,嘗試其他可能的選擇。
對應代碼path.pop()
作用:撤銷當前層的選擇,保證路徑的正確性,避免污染其他分支。
示例:組合問題中,當嘗試完以?i?開頭的所有組合后,移除?i,嘗試下一個數字。

?代碼框架模板
function backtrack(路徑, 選擇列表) {if (滿足終止條件) {將路徑加入結果;return;}for (選擇 in 選擇列表) {做選擇:將選擇加入路徑;backtrack(路徑, 新的選擇列表); // 進入下一層遞歸撤銷選擇:將選擇從路徑移除;    // 回溯}
}
關鍵點解析
  1. 路徑的維護
    path?數組記錄當前遞歸路徑的選擇,必須通過?push?和?pop?確保狀態正確。

  2. 遞歸與回溯的關系
    遞歸是縱向深入探索一條路徑,回溯是橫向嘗試其他可能的選擇。遞歸的終點是終止條件,回溯的觸發點是遞歸返回后的?pop

  3. 剪枝優化
    在組合問題中,通過以下兩種剪枝大幅減少遞歸次數:

    • 剩余數字不足path.length + (9 - i + 1) < k
      例如:如果還需要選 2 個數字,但剩余可用數字只有 1 個,直接終止。

    • 和超過目標值sum + i > n
      當前路徑和已經超過?n,無需繼續遞歸

?


總結

該問題通過回溯算法枚舉所有可能的組合,結合剪枝策略(剩余數字不足、和超過目標值)顯著提高效率。核心在于:

  1. 遞增選擇數字:避免重復組合。

  2. 剪枝優化:減少不必要的遞歸調用。

  3. 回溯機制:撤銷選擇以嘗試其他可能。

這種模式適用于許多組合問題,如子集、排列、組合總和等。

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

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

相關文章

從AI大模型到MCP中臺:構建下一代智能服務的核心架構

從AI大模型到MCP中臺&#xff1a;構建下一代智能服務的核心架構 引言&#xff1a;AI大模型帶來的服務重構革命 在ChatGPT掀起全球AI熱潮的今天&#xff0c;大模型展現出的驚人能力正在重塑整個軟件服務架構。但鮮為人知的是&#xff0c;真正決定AI服務成敗的不僅是模型本身&a…

美團小程序 mtgsig1.2 拼好飯案例 分析 mtgsig

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 逆向分析 美團網頁、小程序、app全是指…

【大模型基礎_毛玉仁】5.5 模型編輯應用

目錄 5.5 模型編輯應用5.5.1 精準模型更新5.5.2 保護被遺忘權5.5.3 提升模型安全 5.5 模型編輯應用 大語言模型面臨更新成本高、隱私保護難、安全風險大等問題。模型編輯技術&#xff1a; 通過細粒度修改預訓練模型&#xff0c;避免從頭訓練&#xff0c;降低更新成本&#xff…

揭秘:父子組件之間的傳遞

基礎知識 組件與組件之間有三大方面的知識點&#xff1a; 子組件通過props defineProps&#xff08;{}&#xff09;接收父組件傳遞到參數和方法&#xff1b;子組件可以通過定義 emit 事件&#xff0c;向父組件發送事件&#xff1b;父組件調用子組件通過defineExpose 導出的方法…

微前端實現方案對比Qiankun VS npm組件

架構層面&#xff1a; 1、Qiankun是典型的微前端架構&#xff0c;側重構建多個獨立前端應用協同工作的架構&#xff0c;主應用負責自用用的加載、卸載和通信&#xff1b;子應用不限制&#xff0c;可以是VUE、React等&#xff1b; 2、Qiankun松耦合&#xff0c;各個自應用獨立…

可編輯160頁PPT | 營銷流程和管理數字化轉型規劃

薦言分享&#xff1a;隨著技術的發展和消費者行為的變化&#xff0c;傳統營銷方式已難以滿足現代企業的需求。企業需要借助數字化手段&#xff0c;對營銷流程進行全面梳理和優化&#xff0c;提升營銷活動的精準度和效率。同時&#xff0c;通過數字化營銷管理&#xff0c;企業可…

Ecovadis認證需要準備哪些材料?

Ecovadis認證&#xff0c;作為全球領先的企業社會責任&#xff08;CSR&#xff09;評估平臺&#xff0c;其準備材料的過程不僅需要詳盡無遺&#xff0c;更要體現出企業在環境、社會、勞工和倫理四大方面的卓越實踐與持續改進的決心。 首先&#xff0c;環境管理方面&#xff0c…

程序化廣告行業(45/89):RTB競價后續流程、結算規則及相關要點解讀

程序化廣告行業&#xff08;45/89&#xff09;&#xff1a;RTB競價后續流程、結算規則及相關要點解讀 大家好&#xff01;一直以來&#xff0c;我都希望能和大家一起在程序化廣告這個領域不斷探索、共同成長&#xff0c;這也是我寫這系列博客的初衷。之前我們了解了程序化廣告…

權重參數矩陣

目錄 1. 權重參數矩陣的定義與作用 2. 權重矩陣的初始化與訓練 3. 權重矩陣的解讀與分析 (1) 可視化權重分布 (2) 統計指標分析 4. 權重矩陣的常見問題與優化 (1) 過擬合與欠擬合 (2) 梯度問題 (3) 權重對稱性問題 5. 實際應用示例 案例1&#xff1a;全連接網絡中的…

文法 2025/3/3

文法的定義 一個文法G是一個四元組&#xff1a;G(,,S,P) &#xff1a;一個非空有限的終極符號集合。它的每個元素稱為終極符號或終極符&#xff0c;一般用小寫字母表示。終極符號是一個語言不可再分的基本符號。 &#xff1a;一個非空有限的非終極符號集合。它的每個元素稱為…

字符串復習

344:反轉字符串 編寫一個函數&#xff0c;其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給出。 不要給另外的數組分配額外的空間&#xff0c;你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。 示例 1&#xff1a; 輸入&#xff1a;s ["…

【數據結構】算法效率的雙刃劍:時間復雜度與空間復雜度

前言 在算法的世界里&#xff0c;效率是衡量算法優劣的關鍵標準。今天&#xff0c;就讓我們深入探討算法效率的兩個核心維度&#xff1a;時間復雜度和空間復雜度&#xff0c;幫助你在算法設計的道路上更進一步。 一、算法效率&#xff1a;衡量算法好壞的關鍵 算法的效率主要…

Java基礎-26-多態-認識多態

在Java編程中&#xff0c;多態&#xff08;Polymorphism&#xff09; 是面向對象編程的核心概念之一。通過多態&#xff0c;我們可以編寫更加靈活、可擴展的代碼。本文將詳細介紹什么是多態、如何實現多態&#xff0c;并通過具體的例子來幫助你更好地理解這一重要概念。 一、什…

使用自定義的RTTI屬性對對象進行流操作

由于歷史原因&#xff0c;在借鑒某些特定出名的游戲引擎中&#xff0c;不知道當時的作者的意圖和編寫方式 特此做這篇文章。&#xff08;本文出自游戲編程精粹4 中 使用自定義的RTTI屬性對對象進行流操作 文章&#xff09; 載入和 保存 關卡&#xff0c;并不是一件容易辦到的事…

周總結aa

上周學習了Java中有關字符串的內容&#xff0c;與其有關的類和方法 學習了static表示靜態的相關方法和類的使用。 學習了繼承(extends) 多態&#xff08;有繼承關系&#xff0c;有父類引用指向子類對象&#xff09; 有關包的知識&#xff0c;final關鍵字的使用&#xff0c;及有…

密碼學基礎——密碼學相關概念

目錄 1.1 密碼系統&#xff08;Cryptosystem&#xff09; 1.2 密碼編碼學 1.3 密碼分析學 1.4 基于算法保密 1.5 基于密鑰保密 1.6密碼系統的設計要求 1.7 單鑰體制 1.8 雙鑰體制 密鑰管理 1.1 密碼系統&#xff08;Cryptosystem&#xff09; 也稱為密碼體制&#xff0…

初始JavaEE篇 —— Mybatis-plus 操作數據庫

找往期文章包括但不限于本期文章中不懂的知識點&#xff1a; 個人主頁&#xff1a;我要學編程程(?_?)-CSDN博客 所屬專欄&#xff1a;JavaEE 目錄 前言 Mybatis-plus 快速上手 Mybatis-plus 復雜操作 常用注解 TableName TableField TableId 打印日志 條件構造器 …

PyQt6實例_批量下載pdf工具_主線程啟用線程池

目錄 前置&#xff1a; 代碼&#xff1a; 視頻&#xff1a; 前置&#xff1a; 1 本系列將以 “PyQt6實例_批量下載pdf工具”開頭&#xff0c;放在 【PyQt6實例】 專欄 2 本系列涉及到的PyQt6知識點&#xff1a; 線程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信號與…

1.2 斐波那契數列模型:LeetCode 面試題 08.01. 三步問題

動態規劃解三步問題&#xff1a;LeetCode 面試題 08.01. 三步問題 1. 題目鏈接 LeetCode 面試題 08.01. 三步問題 題目要求&#xff1a;小孩上樓梯&#xff0c;每次可以走1、2或3步&#xff0c;計算到達第 n 階臺階的不同方式數&#xff0c;結果需對 1e9 7 取模。 2. 題目描述…

UE5 學習筆記 FPS游戲制作30 顯示擊殺信息 水平框 UI模板(預制體)

文章目錄 一制作單條死亡信息框水平框的使用創建一個水平框添加子元素調整子元素順序子元素的布局插槽尺寸填充對齊 制作UI 根據隊伍&#xff0c;設置文本的名字和顏色聲明變量 將變量設置為構造參數根據隊伍&#xff0c;設置文本的名字和顏色在構造事件中&#xff0c;獲取玩家…