算法訓練營day24 回溯算法③ 93.復原IP地址 、78.子集、 90.子集II

????????今天繼續回溯算法的專題,第三篇博客!

93.復原IP地址

輸入:s = "25525511135"
輸出:["255.255.11.135","255.255.111.35"]

????????切割字符串為4段,當進行到第四段的時候對第四段字符串進行判斷,是否可以輸出到result數組中,優化:通過檢查剩余位數來進行剪枝

回溯過程

  • 遞歸參數

????????startIndex一定是需要的,因為不能重復分割,記錄下一層遞歸分割的起始位置。本題我們還需要一個變量pointNum,記錄添加逗點的數量。(記錄已經是多少段了)

  • 遞歸終止條件

????????本題明確要求只會分成4段,所以不能用切割線切到最后作為終止條件,而是分割的段數作為終止條件。pointNum表示逗點數量,pointNum為3說明字符串分成了4段了。然后驗證一下第四段是否合法,如果合法就加入到結果集里

  • 單層搜索的邏輯

????????在for (int i = startIndex; i < s.size(); i++)循環中 [startIndex, i] 這個區間就是截取的子串,需要判斷這個子串是否合法。

  • 如果合法就在字符串后面加上符號.表示已經分割。
  • 如果不合法就結束本層循環,如圖中剪掉的分支:

????????然后就是遞歸和回溯的過程:遞歸調用時,下一層遞歸的startIndex要從i+1開始,同時記錄分割符的數量pointNum 要 +1。回溯的時候,就將剛剛加入的分隔符.?刪掉就可以了,pointNum也要-1。

判斷子串是否合法

主要考慮到如下三點:

  • 段位以0為開頭的數字不合法
  • 段位里有非正整數字符不合法
  • 段位如果大于255了不合法

回溯模版

void backtracking(參數) {if (終止條件) {存放結果;return;}for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小)) {處理節點;backtracking(路徑,選擇列表); // 遞歸回溯,撤銷處理結果}
}

代碼實現

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:result = []self.backtracking(s, 0, 0, '', result)return resultdef backtracking(self, s, start_index, point_num, current, result):# start_index: 標注下一層的循環開始位置# point_num: 切割逗點數量# current: 單個字符串保存# result: 結果數組集合存儲if point_num == 3: #分割結束if self.is_valid(s, start_index, len(s) - 1):# 符合左閉右閉, 數組索引方式current += s[start_index: ]# 添加最后一段字符串result.append(current)return for i in range(start_index, len(s)):# range函數左閉右開# 判斷該段字符是否符合, 如果不符合停止該層遞歸if self.is_valid(s, start_index, i): # 理解i的作用片段, 符合要求sub = s[start_index:i+ 1] # 切片左閉右開self.backtracking(s, i + 1, point_num + 1, current + sub + '.', result)# 理解python中的引用復制和復制賦值!else:breakdef is_valid(self, s, start, end):# 左閉右閉if start > end:return Falseif s[start] == '0' and start != end:# 開頭數字為0return Falsenum = 0for i in range(start, end + 1):if not s[i].isdigit():return False # 判斷是否遇到非數字字符num = num * 10 + int(s[i])if num > 255:return Falsereturn True

版本2(了解即可)

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:results = []self.backtracking(s, 0, [], results)return resultsdef backtracking(self, s, index, path, results):if index == len(s) and len(path) == 4:results.append('.'.join(path))returnif len(path) > 4:  # 剪枝returnfor i in range(index, min(index + 3, len(s))):if self.is_valid(s, index, i):sub = s[index:i+1]path.append(sub)self.backtracking(s, i+1, path, results)path.pop()def is_valid(self, s, start, end):if start > end:return Falseif s[start] == '0' and start != end:  # 0開頭的數字不合法return Falsenum = int(s[start:end+1])return 0 <= num <= 255

78.子集

????????簡單題目,屬于組合范疇(普通模版級別),大家可以自己畫一畫樹狀圖

回溯過程

  • 遞歸函數參數

????????全局變量數組path為子集收集元素,二維數組result存放子集組合。(也可以放到遞歸函數參數里)遞歸函數參數在上面講到了,需要startIndex。

  • 遞歸終止條件

? ? ? ? 所剩集合為空的時候,就是葉子節點。那么什么時候剩余集合為空呢?就是startIndex已經大于數組的長度了,就終止了,因為沒有元素可取了

  • 單層搜索邏輯

????????求取子集問題,不需要任何剪枝!因為子集就是要遍歷整棵樹

class Solution:def subsets(self, nums: List[int]) -> List[List[int]]:result = []path = []self.backtracking(nums, 0, path, result)return resultdef backtracking(self, nums, startIndex, path, result):result.append(path[:])for i in range(startIndex, len(nums)):path.append(nums[i])self.backtracking(nums, i + 1, path, result)path.pop()

90.子集II

????????整數數組?nums?,其中可能包含重復元素,這個是困難的,所以要去重

????????之前我們也做過一道去重的題目,更具體的說,這個就是“樹枝去重”和“樹層去重”的區別,毫無疑問,我們這道題仍然是樹層去重,即樹枝上存在相同元素是允許的,而書層上出現相同元素是不被允許的

? ? ? ? 整體思路如下:是和之前“去重”思路完全一樣的題目

代碼實現(增加去重)

class Solution:def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:result = []path = []nums.sort()# 注意排序,這樣相同的數字才可以放在一起,方便后續處理self.backtracking(nums, 0, path, result)return resultdef backtracking(self, nums, startIndex, path, result):result.append(path[:])for i in range(startIndex, len(nums)):if i > startIndex and nums[i] == nums[i - 1]: # 第一個遇到不要處理continuepath.append(nums[i])self.backtracking(nums, i + 1, path, result)path.pop()

代碼實現(利用used數組)

class Solution:def subsetsWithDup(self, nums):result = []path = []used = [False] * len(nums)nums.sort()  # 去重需要排序self.backtracking(nums, 0, used, path, result)return resultdef backtracking(self, nums, startIndex, used, path, result):result.append(path[:])  # 收集子集for i in range(startIndex, len(nums)):# used[i - 1] == True,說明同一樹枝 nums[i - 1] 使用過# used[i - 1] == False,說明同一樹層 nums[i - 1] 使用過# 而我們要對同一樹層使用過的元素進行跳過if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:continuepath.append(nums[i])used[i] = Trueself.backtracking(nums, i + 1, used, path, result)used[i] = Falsepath.pop()

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

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

相關文章

jeccg-boot框架實現xls模板導出功能

文章目錄一、后端部分二、前端部分三、模板制作一、后端部分 //1、在application-dev.yml文件增加模板路徑path :#模板路徑saxls: /data/opt/saxls/ //2、控制層寫法 public class sabassalController extends JeecgController<sabassalVo, IsabassalService> {Autowired…

LangChain4j入門:Java開發者的AI應用開發指南

&#x1f680; 在AI浪潮席卷全球的今天&#xff0c;Java開發者如何快速上手大語言模型應用開發&#xff1f;LangChain4j為我們提供了完美的解決方案&#xff01; 前言&#xff1a;為什么Java開發者需要LangChain4j&#xff1f; 想象一下&#xff0c;你正在開發一個企業級應用&…

相機光學(五十)——Depth AF

1.什么是Depth AFDepth AF&#xff08;景深自動對焦&#xff09;&#xff0c;也稱為 Depth-of-Field AF&#xff08;景深對焦&#xff09; 或 DEP AF&#xff0c;是一種基于景深范圍的自動對焦技術&#xff0c;核心目標是&#xff1a;確保從前景到背景的一整段距離都在清晰景深…

Unity 堆棧分析實戰指南 C#

Unity 堆棧分析實戰指南 提示&#xff1a;內容純個人編寫&#xff0c;歡迎評論點贊&#xff0c;來指正我。 文章目錄Unity 堆棧分析實戰指南1. 前言2. 什么是堆棧3. Unity 中的堆棧4. 堆棧分析工具5. 如何進行堆棧分析6. 實戰案例分析案例 1: 性能瓶頸分析案例 2: 內存泄漏檢測…

AE MDX L6 L12 L18 電源手側操作使用說明

AE MDX L6 L12 L18 電源手側操作使用說明

Gemini Function Calling 和 Qwen3 Embedding和ReRanker模型

Gemini API 的函數調用&#xff08;Function Calling&#xff09;功能。它解決了傳統大語言模型&#xff08;LLM&#xff09;的一個關鍵局限&#xff1a;LLM 本身是基于訓練數據的“知識庫”&#xff0c;擅長生成文本和回答問題&#xff0c;但無法直接執行代碼、訪問實時數據或…

??VMware Workstation Pro 17.5.0 安裝教程 - 詳細步驟圖解(附下載+激活)?

VMware Workstation Pro 17.5.0 是一款功能強大的虛擬機軟件&#xff0c;允許用戶在一臺計算機上同時運行多個操作系統&#xff08;如 Windows、Linux、macOS&#xff09;&#xff0c;適用于開發、測試、運維及學習環境搭建。本教程提供 ??詳細安裝步驟??&#xff0c;包括 …

端到端神經網絡視頻編解碼器介紹

一、技術演進&#xff1a;從模塊優化到全局智能的范式躍遷 傳統編解碼器的效率天花板&#xff08;1990-2017&#xff09; 架構局限&#xff1a;H.264/HEVC依賴手工設計的運動估計、DCT變換、熵編碼模塊&#xff0c;各模塊獨立優化導致全局效率損失。高分辨率瓶頸&#xff1a;4…

Kubernetes (k8s)環境重啟Pod方式總結

前言&#xff1a;在 Kubernetes (k8s) 中&#xff0c;沒有直接的命令如 kubectl restart pod 來重啟 Pod&#xff0c;因為 Pod 的生命周期由控制器&#xff08;如 Deployments、StatefulSets 或 ReplicaSets&#xff09;管理。重啟操作本質上是通過刪除并重建 Pod 來實現的&…

OOA、OOD 與 OOP:面向對象范式的核心支柱詳解

作為軟件系統架構的核心范式&#xff0c;面向對象方法貫穿軟件開發生命周期。OOA、OOD 和 OOP 分別代表分析、設計和實現三個關鍵階段&#xff0c;共同構成一個連貫的工程體系。一、OOA (Object-Oriented Analysis&#xff0c;面向對象分析) 目標&#xff1a;理解問題域&#x…

GBase 8a 與 Spring Boot + MyBatis 整合實戰:從環境搭建到CRUD操作

一、引言 在企業級數據管理場景中&#xff0c;GBase數據庫憑借其高性能的數據分析能力和對SQL標準的良好兼容性&#xff0c;成為金融、電信等行業的常用選擇。本文將詳細演示如何將GBase數據庫與Spring Boot、MyBatis框架整合&#xff0c;實現高效的數據持久化操作&#xff0c…

功能安全之BIST的基本原理

BIST&#xff08;Built-In Self-Test&#xff0c;內建自測試&#xff09;是一種將測試功能直接集成到集成電路&#xff08;IC&#xff09;或系統內部的設計方法。其基本原理的核心在于&#xff1a;讓被測試電路自身&#xff08;或借助少量專用硬件&#xff09;來生成測試激勵、…

Linux 程序地址空間

目錄 Ⅰ、什么是程序地址空間&#xff1f; Ⅱ、虛擬地址空間是什么樣的&#xff1f; 一、虛擬地址空間和頁表 1、什么是頁表&#xff1f; 2、什么是虛擬地址空間&#xff1f; 3、什么是vm_area_struct? Ⅲ、為什么要用虛擬地址空間&#xff1f; 一、進程的獨立性 二、…

【iOS】消息傳遞和消息轉發

文章目錄前言一、消息傳遞&#xff1a;objc_msgSend 的“查字典遞歸找家長”流程1. 第一步&#xff1a;查“最近調用記錄”&#xff08;方法緩存&#xff09;—— 最快即快速查找&#xff01;2. 第二步&#xff1a;翻“自己的字典”&#xff08;類方法列表查找&#xff09;——…

MySQL查詢優化與事務實戰指南

本節用到的員工信息管理表結構放到資源中&#xff0c;需要的同學自取。本節內容以此表為示例&#xff1a; 面試題&#xff1a;innodb與myisam的區別。 外鍵&#xff0c;事務 特性InnoDBMyISAM事務支持支持不支持外鍵支持不支持鎖粒度行級鎖表級鎖索引結構聚簇索引非聚簇索引崩…

Windows 10/11 磁盤清理操作指南:徹底解決系統盤空間不足問題

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#,Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開發…

b-up:Enzo_Mi:深度學習基礎知識

1.最近鄰差值&#xff08;Neareast Neighbor Interpolation&#xff09; 插值算法 &#xff5c; 最近鄰插值法_嗶哩嗶哩_bilibili 上圖中最后一行&#xff0c;第一個圖像&#xff0c;因為目標像素&#xff08;放大后&#xff0c;位于第1行第0列的像素&#xff09;距離它最近的…

微信小程序商品結算功能

整體結算流程概述微信小程序的商品結算涉及前端交互、API調用和數據管理。典型流程包括&#xff1a;用戶交互&#xff1a;用戶選擇商品、填寫地址和時間。數據獲取&#xff1a;從小程序緩存或后端服務器獲取訂單信息。邏輯處理&#xff1a;驗證參數、應用紅包折扣。提交訂單&am…

2025年7月份最新一區算法——向光生長算法

注&#xff1a;該算法已按照智能優化算法APP標準格式進行整改&#xff0c;可直接集成到APP中&#xff0c;方便大家與自己的算法進行對比。&#xff08;近期智能優化算法APP將會迎來超級大更新&#xff01;請時刻保持關注哦&#xff01;&#xff09;向光生長算法&#xff08;Pho…

腳手架新建Vue2/Vue3項目時,項目文件內容的區別

一. package.json vue版本號不同vue2中會多一個依賴&#xff1a;vue-template-compiler&#xff0c;作用是預編譯Vue2模板為渲染函數&#xff0c;減少運行時開銷。vue-template-compiler與vue版本要保持一致&#xff0c;否則會報錯。eslintConfig中的extends不同 eslintConfig…