【算法】回溯算法

回溯算法

什么是回溯

人生無時不在選擇。在選擇的路口,你該如何抉擇 .....

回溯: 是一種選優搜索法,又稱為試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇并不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。

回溯,計算機算法,回溯法也稱試探法,它的基本思想是:從問題的某一種狀態(初始狀態)出發,搜索從這種狀態出發所能達到的所有“狀態”,當一條路走到“盡頭”的時候(不能再前進),再后退一步或若干步,從另一種可能“狀態”出發,繼續搜索,直到所有的“路徑”(狀態)都試探過。這種不斷“前進”、不斷“回溯”尋找解的方法,就稱作“回溯法”。--百度百科

一個例子看回溯

給下圖的圖頂點進行三種顏色著色(紅、黃、藍)

要求:

  1. 每個頂點的顏色只能從紅、黃、藍中選一個種。

  2. 相鄰的兩種顏色不能為同一種顏色。

思考方式

暴力推測,查找各種可能...

image-20241020173912533

樹型策略

暴力查找結果(從上向下[第n=1行開始],從左邊開始):

  1. n=1,先取紅,n=2取紅

  1. [紅、紅、紅], [紅,紅,黃],[紅,紅,藍]; [紅,黃, 紅],[紅,黃,黃],[紅,黃,藍];[紅,藍,紅],[紅,藍,黃],[紅,藍,藍]

  2. n=1, n=2取黃

  3. n=2, n=3,取藍色

  1. 回溯到根節點,走n=1,取黃色

回溯的一般規律

我們可以針對以上的找色問題,給出以下的一般的解決方案。

  1. 初始化: 初始化變量

  2. 找一個合法值,通過遍歷(+1/-1)選取所有的可能[可以認為是樹的深度]

  3. 棧記錄

  4. 遞歸調用

  5. 回溯已經使用的值

經典題目

全排列

題目

[力扣46] 46. 全排列 - 力扣(LeetCode)

題目描述

給定一個不含重復數字的數組 nums ,返回其 所有可能的全排列 。你可以 按任意順序 返回答案。

示例 1:

輸入:nums = [1,2,3]
輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

輸入:nums = [0,1]
輸出:[[0,1],[1,0]]

示例 3:

輸入:nums = [1]
輸出:[[1]]
解決方案

image-20241023202329664

提交模版
public List<List<Integer>> permute(int[] nums) { ? }
參考實現
class Solution {
?private List<List<Integer>> list = new ArrayList<>();private Stack<Integer> stack = new Stack<>();
?public List<List<Integer>> permute(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);return list;}
?private void dfs(int[] nums, int depth, boolean[] isUsed) {if (depth == nums.length) {list.add(new ArrayList<>(stack));return;}
?for (int i = 0; i < nums.length; i++) {if (isUsed[i]) {continue;}stack.push(nums[i]);isUsed[i] = true;dfs(nums, depth + 1, isUsed);stack.pop();isUsed[i] = false;}}
}

全排列II

題目

[力扣47] 47. 全排列 II - 力扣(LeetCode)

題目描述

給定一個可包含重復數字的序列 nums按任意順序 返回所有不重復的全排列。

示例 1:

輸入:nums = {1,1,2}
輸出:
{{1,1,2},{1,2,1},{2,1,1}
}

示例 2:

輸入:nums = [1,2,3]
輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
解題思路
提交模版
public List<List<Integer>> permuteUnique(int[] nums) { ? }
參考實現
class Solution {private final List<List<Integer>> list = new ArrayList<>();private final Stack<Integer> stack = new Stack<>();private final Set<List<Integer>> sets = new HashSet<>();
?
?public List<List<Integer>> permuteUnique(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);list.addAll(sets);return list;}
?/*** @param nums* @param depth  遞歸的深度,從底層開始到最后一層* @param isUsed 判斷當前數據是否使用過*/private void dfs(int[] nums, int depth, boolean[] isUsed) {if (depth == nums.length) {sets.add(new ArrayList<>(stack));return;}
?Set<Integer> set = new HashSet<>();//記錄重復數據for (int i = 0; i < nums.length; i++) { //遍歷數組//數據重復或者使用過則跳過當前數據if (isUsed[i] ) continue;// set.add(nums[i]); //記錄選擇的數據//  System.out.println("set-->" + set);stack.push(nums[i]);isUsed[i] = true;dfs(nums, depth + 1, isUsed);stack.pop();isUsed[i] = false;}}
}

子集問題

題目

[力扣78] 78. 子集 - 力扣(LeetCode)

題目描述

給你一個整數數組 nums ,數組中的元素 互不相同 。返回該數組所有可能的子集(冪集)。

解集 不能 包含重復的子集。你可以按 任意順序 返回解集。

示例 1:

輸入:nums = [1,2,3]
輸出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

輸入:nums = [0]
輸出:[[],[0]]
解題思路

創建策略樹

我們會發現出現大量的無效操作數據。對策略樹進行"剪枝"處理。

剪枝- 我們“剪掉”了不滿足約束條件的搜索分支,避免許多無意義的嘗試,從而提高了搜索效率。

提交模版
 public List<List<Integer>> subsets(int[] nums) { }
參考實現
class Solution {List<List<Integer>> list = new ArrayList<>();Stack<Integer> stack = new Stack<>();
?public List<List<Integer>> subsets(int[] nums) {dfs(nums, 0);return list;}
?private void dfs(int[] nums, int startIndex) {
?list.add(new ArrayList<>(stack));if (startIndex >= nums.length) {return;}
?for (int i = startIndex; i < nums.length; i++) {stack.push(nums[i]);dfs(nums, i + 1);stack.pop();
?}}
}

剪枝優化

class Solution {private final List<List<Integer>> list = new ArrayList<>();private final List<Integer> stack = new ArrayList<>();
?public List<List<Integer>> subsets(int[] nums) {boolean[] isUsed = new boolean[nums.length];dfs(nums, 0, isUsed);return list;}
?private void dfs(int[] nums, int startIndex, boolean[] isUsed) {
?list.add(new ArrayList<>(stack)); //記錄掃描的所有節點for (int i = startIndex; i < nums.length; i++) {if (isUsed[i])continue;stack.add(nums[i]);isUsed[i] = true;dfs(nums, i + 1,isUsed);stack.remove(stack.size()-1);isUsed[i] = false;
?}}
}

子集II

題目

[力扣90] 90. 子集 II - 力扣(LeetCode)

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

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

相關文章

SpringAI系列 - RAG篇(三) - ETL

目錄 一、引言二、組件說明三、集成示例一、引言 接下來我們介紹ETL框架,該框架對應我們之前提到的階段1:ETL,主要負責知識的提取和管理。ETL 框架是檢索增強生成(RAG)數據處理的核心,其將原始數據源轉換為結構化向量并進行存儲,確保數據以最佳格式供 AI 模型檢索。 …

2025 docker可視化管理面板DPanel的安裝

1.什么是 DPanel &#xff1f; DPanel 是一款 Docker 可視化管理面板&#xff0c;旨在簡化 Docker 容器、鏡像和文件的管理。它提供了一系列功能&#xff0c;使用戶能夠更輕松地管理和部署 Docker 環境。 軟件特點&#xff1a; 可視化管理&#xff1a;提供直觀的用戶界面&#…

基于Python的深度學習音樂推薦系統(有配套論文)

音樂推薦系統 提供實時音樂推薦功能&#xff0c;根據用戶行為和偏好動態調整推薦內容 Python、Django、深度學習、卷積神經網絡 、算法 數據庫&#xff1a;MySQL 系統包含角色&#xff1a;管理員、用戶 管理員功能&#xff1a;用戶管理、系統設置、音樂管理、音樂推薦管理、系…

微信小程序---計劃時鐘設計與實現

微信小程序-計劃時鐘已上線,歡迎各位小伙伴的測試和使用~(微信小程序搜計劃時鐘即可使用) 在這篇博客中,我們將探討如何在微信小程序中設計和實現一個任務管理功能,該功能允許用戶添加、刪除和查看任務。任務管理系統的核心是基于日期和時間的任務管理,可以設置任務的開…

RPA-實例(UiPath )

UiPath 是一個流行的機器人流程自動化(RPA)工具,用于自動化重復性任務。以下是一個簡單的實例,展示如何使用 UiPath 自動化一個常見的任務:從 Excel 文件中讀取數據并將其輸入到網頁表單中。 實例:從 Excel 讀取數據并自動填寫網頁表單 步驟 1:準備工作 安裝 UiPath S…

華為固態電池引發的思索

華為固態電池真牛&#xff01; 超長續航&#xff1a;單次充電即可行駛3000公里 極速充電&#xff1a;五分鐘內充滿80% 極致安全&#xff1a;不可燃、不漏液 長壽命設計&#xff1a;循環壽命達10000次以上 如上是華為電池展示的優勢項&#xff0c;每一條都讓我們心動不已。…

算法分析—— 《歸并排序》

《排序數組》 題目描述&#xff1a; 給你一個整數數組 nums&#xff0c;請你將該數組升序排列。 你必須在 不使用任何內置函數 的情況下解決問題&#xff0c;時間復雜度為 O(nlog(n))&#xff0c;并且空間復雜度盡可能小。 示例 1&#xff1a; 輸入&#xff1a;nums [5,2…

UEFI Spec 學習筆記---11 - Protocols — UEFI Driver Model(1)

11.UEFI Driver Model 遵循 UEFI model 的 EFI driver 是不允許去遍歷所有的 controller 來識別需要安裝到哪個 controller 上的&#xff0c;而是通過 EFI_BOOT_SERVICES 的 ConnectController 和調用 Binding Driver 來實現&#xff1b; 具體實現如下&#xff1a; CoreConne…

10G EPON光模塊

一、10G EPON對稱光模塊 工作模式&#xff1a;上行突發接收、下行連續發射。 工作原理&#xff1a;當需要發送信號時&#xff0c;系統信號通過光模塊的電接口把信號傳送到驅動芯片&#xff0c;芯片處理后&#xff0c;驅動激光器發出調制光信號&#xff0c;經光纖發到遠端&…

整合SaToken 實現登錄功能

整合SaToken 實現登錄功能 1.整合redis 1.1添加相關依賴 // 省略...<!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Redi…

Vue 項目中逐步引入 TypeScript 的類型檢查

在現有的 Vue 項目中逐步引入 TypeScript 的類型檢查 本文源于一道面試題&#xff1a;注&#xff1a;兩種問法一個意思哈&#xff01;&#xff01; 問題一&#xff1a;“ 老項目Js寫的&#xff0c;如何輕量方式享受 ts 類型&#xff1f;” 問題二&#xff1a;“如何 在現有的 …

python后端調用Deep Seek API

python后端調用Deep Seek API 需要依次下載 ●Ollama ●Deepseek R1 LLM模型 ●嵌入模型nomic-embed-text / bge-m3 ●AnythingLLM 參考教程&#xff1a; Deepseek R1打造本地化RAG知識庫:安裝部署使用詳細教程 手把手教你&#xff1a;deepseek R1基于 AnythingLLM API 調用本地…

本地部署MindSearch(開源 AI 搜索引擎框架),然后上傳到 hugging face的Spaces——L2G6

部署MindSearch到 hugging face Spaces上——L2G6 任務1 在 官方的MindSearch頁面 復制Spaces應用到自己的Spaces下&#xff0c;Space 名稱中需要包含 MindSearch 關鍵詞&#xff0c;請在必要的步驟以及成功的對話測試結果當中 實現過程如下&#xff1a; 2.1 MindSearch 簡…

matlab下載安裝圖文教程

【matlab介紹】 MATLAB是一款由美國MathWorks公司開發的專業計算軟件&#xff0c;主要應用于數值計算、可視化程序設計、交互式程序設計等高科技計算環境。以下是關于MATLAB的簡要介紹&#xff1a; MATLAB是MATrix LABoratory&#xff08;矩陣實驗室&#xff09;的縮寫&#…

捷米特 JM - RTU - TCP 網關應用 F - net 協議轉 Modbus TCP 實現電腦控制流量計

一、項目背景 在某工業生產園區的供水系統中&#xff0c;為了精確監測和控制各個生產環節的用水流量&#xff0c;需要對分布在不同區域的多個流量計進行集中管理。這些流量計原本采用 F - net 協議進行數據傳輸&#xff0c;但園區的監控系統基于 Modbus TCP 協議進行數據交互&…

4.1 Hugging Face Datasets實戰:構建企業級數據流水線

Hugging Face Datasets實戰:構建企業級數據流水線 一、Datasets庫核心優勢 1.1 企業級數據處理需求全景 # 支持的數據格式示例 data_formats = {"結構化數據": ["CSV", "Parquet", "SQL"]

深入解析隊列與廣度優先搜索(BFS)的算法思想:原理、實現與應用

目錄 1. 隊列的基本概念 2. 廣度優先搜索&#xff08;BFS&#xff09;的基本概念 3. 隊列在BFS中的作用 4. BFS的實現細節 5. C實現BFS 6. BFS的應用場景 7. 復雜度分析 8. 總結 1. 隊列的基本概念 隊列&#xff08;Queue&#xff09;是一種先進先出&#xff08;FIFO, …

【學術投稿-第四屆材料工程與應用力學國際學術會議(ICMEAAE 2025】材料工程與應用力學的探討

重要信息 官網&#xff1a;www.icmeaae.com 時間&#xff1a;2025年3月7-9日 地點&#xff1a;中國西安 簡介 第四屆材料工程與應用力學&#xff08;ICMEAAE 2025&#xff09;將于2025年3月7日至9日在中國西安召開。本次會議將重點討論材料科學、應用力學等領域的最新研究進…

間隔連續問題

間隔連續問題 1. 數據結構&#xff1a;某游戲公司記錄的用戶每日登錄數據 表名&#xff1a;game_user 字段名&#xff1a;id&#xff08;用戶id&#xff09;、dt&#xff08;日期&#xff09; 2. 需求&#xff1a; ① 創建表 ② 計算每個用戶最大的連續登錄天數&#xff0c…

EasyRTC輕量級SDK:智能硬件音視頻通信資源的高效利用方案

在智能硬件這片廣袤天地里&#xff0c;每一份資源的精打細算都關乎產品的生死存亡。隨著物聯網技術的疾速演進&#xff0c;實時音視頻通信功能已成為眾多設備的標配。然而&#xff0c;硬件資源的捉襟見肘&#xff0c;讓開發者們常常陷入兩難境地。EasyRTC&#xff0c;以它的極致…