算法訓練營day46 647. 回文子串、516.最長回文子序列、動態規劃總結篇

? ? ? ? 今天是動態規劃的最后一篇內容了,本篇主要是針對回文字符串這種“與眾不同”的遞推規律來進行講解

647. 回文子串

????????統計并返回這個字符串中?回文子串?的數目

暴力解法

????????兩層for循環,遍歷區間起始位置和終止位置,然后還需要一層遍歷判斷這個區間是不是回文。所以時間復雜度:O(n^3)

動態規劃

  • 確定dp數組(dp table)以及下標的含義

????????如果大家做了很多這種子序列相關的題目,在定義dp數組的時候 很自然就會想題目求什么,我們就如何定義dp數組。

????????絕大多數題目確實是這樣,不過本題如果我們定義,dp[i] 為 下標i結尾的字符串有 dp[i]個回文串的話,我們會發現很難找到遞歸關系。dp[i] 和 dp[i-1] ,dp[i + 1] 看上去都沒啥關系。所以我們要看回文串的性質。

????????我們在判斷字符串S是否是回文,那么如果我們知道 s[1],s[2],s[3] 這個子串是回文的,那么只需要比較 s[0]和s[4]這兩個元素是否相同,如果相同的話,這個字符串s 就是回文串。那么此時我們是不是能找到一種遞歸關系,也就是判斷一個子字符串(字符串下標范圍[i,j])是否回文,依賴于,子字符串(下標范圍[i + 1, j - 1])) 是否是回文

????????所以為了明確這種遞歸關系,我們的dp數組是要定義成二維dp數組。dp[i][j](布爾類型):表示區間范圍[i,j] (注意是左閉右閉)的子串是否是回文子串,如果是dp[i][j]為true,否則為false。

  • 確定遞推公式(這個地方要和遍歷順序一起理解,遞推公式對于解題非常重要)

????????在確定遞推公式時,就要分析如下幾種情況。整體上是兩種,就是s[i]與s[j]相等,s[i]與s[j]不相等這兩種。

????????當s[i]與s[j]不相等,那沒啥好說的了,dp[i][j]一定是false。

????????當s[i]與s[j]相等時,這就復雜一些了,有如下三種情況

  1. 情況一:下標i 與 j相同,同一個字符例如a,當然是回文子串
  2. 情況二:下標i 與 j相差為1,例如aa,也是回文子串
  3. 情況三:下標:i 與 j相差大于1的時候,例如cabac,此時s[i]與s[j]已經相同了,我們看i到j區間是不是回文子串就看aba是不是回文就可以了,那么aba的區間就是 i+1 與 j-1區間,這個區間是不是回文就看dp[i + 1][j - 1]是否為true。
  • dp數組如何初始化??

????????dp[i][j]初始化為false。

  • 確定遍歷順序

????????遍歷順序可就有點講究了。

????????首先從遞推公式中可以看出,情況三是根據dp[i + 1][j - 1]是否為true,在對dp[i][j]進行賦值true的。dp[i + 1][j - 1] 在 dp[i][j]的左下角所以一定要從下到上,從左到右遍歷,這樣保證dp[i + 1][j - 1]都是經過計算的

????????總而言之,一個道理,都是為了保證dp[i + 1][j - 1]都是經過計算的。

  • 舉例推導dp數組

????????舉例,輸入:"aaa",dp[i][j]狀態如下:

class Solution:def countSubstrings(self, s: str) -> int:dp = [[False] * len(s) for _ in range(len(s))]result = 0for i in range(len(s)-1, -1, -1): #注意遍歷順序for j in range(i, len(s)):if s[i] == s[j]:if j - i <= 1: #情況一 和 情況二result += 1dp[i][j] = Trueelif dp[i+1][j-1]: #情況三result += 1dp[i][j] = Truereturn result

雙指針法

回文子串的對稱中心有兩種情況:

  • 奇數長度的回文子串(如 "aba"):中心是單個字符(示例中的 "b")。
  • 偶數長度的回文子串(如 "abba"):中心是兩個相鄰字符(示例中的 "bb")。

中心擴展法的邏輯是:

  • 枚舉字符串中每個可能的中心(單個字符或相鄰兩個字符)。
  • 從中心向兩側擴展,判斷擴展后的子串是否為回文。
  • 每擴展成功一次,就計數一個回文子串。
class Solution:def countSubstrings(self, s: str) -> int:result = 0for i in range(len(s)):result += self.extend(s, i, i, len(s)) #以i為中心result += self.extend(s, i, i+1, len(s)) #以i和i+1為中心return resultdef extend(self, s, i, j, n):res = 0while i >= 0 and j < n and s[i] == s[j]:i -= 1j += 1res += 1return res

516.最長回文子序列

????????這種回文子序列可以刪除元素是很難想的,因為規律不是很直觀。本題和上題的區別在于:回文子串是要連續的,回文子序列可不是連續的!?

  • 確定dp數組(dp table)以及下標的含義

????????dp[i][j]:字符串s在[i, j]范圍內最長的回文子序列的長度為dp[i][j]

  • 確定遞推公式

????????在判斷回文子串的題目中,關鍵邏輯就是看s[i]與s[j]是否相同。

????????如果s[i]與s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;

????????如果s[i]與s[j]不相同,說明s[i]和s[j]的同時加入 并不能增加[i,j]區間回文子序列的長度,那么分別加入s[i]、s[j]看看哪一個可以組成最長的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

  • dp數組如何初始化

????????當i與j相同,那么dp[i][j]一定是等于1的,即:一個字符的回文子序列長度就是1。其他情況dp[i][j]初始為0就行

  • 確定遍歷順序

????????從遞歸公式中,可以看出,dp[i][j] 依賴于 dp[i + 1][j - 1] ,dp[i + 1][j] 和 dp[i][j - 1],所以遍歷i的時候一定要從下到上遍歷,這樣才能保證下一行的數據是經過計算的

  • 遍歷模擬

class Solution:def longestPalindromeSubseq(self, s: str) -> int:dp = [[0] * len(s) for _ in range(len(s))]for i in range(len(s)):dp[i][i] = 1for i in range(len(s)-1, -1, -1):for j in range(i+1, len(s)):if s[i] == s[j]:dp[i][j] = dp[i+1][j-1] + 2else:dp[i][j] = max(dp[i+1][j], dp[i][j-1])return dp[0][-1]

動態規劃總結篇

代碼隨想錄——動態規劃總結篇

  • 動態規劃基礎(初步感受遞推的關系)

  • 背包問題系列(遞推二維到一維的理解)

  • 打家劫舍系列(線性遞推順序的延伸)

  • 股票系列(dp數組和數據輸出的巧妙設置)*

  • 子序列系列(理解模擬遍歷的重要性)

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

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

相關文章

Qt界面優化

1.QSS在網頁前端開發領域中&#xff0c;CSS 是一個至關重要的部分&#xff0c;描述了一個網頁的 “樣式”&#xff0c;從而起到對網頁美化的作用。所謂樣式&#xff0c;包括不限于大小、位置、顏色、背景、間距、字體等等。網頁開發作為 GUI 的典型代表&#xff0c;也對于其他客…

week1+2+3

408 計組 1.基本組成2.數據的表示和運算定點數&#xff1a;把數字分為定點整數和定點小數分開存儲 浮點數&#xff1a;用科學計數法存儲 原碼 -全部取反-> 反碼 反碼 1->補碼 補碼 -符號位取反->移碼帶余除法&#xff1a;設x,m∈Z&#xff0c;m>0則存在唯一的整數q…

java8中javafx包缺少報錯

今天拉取一個jdk1.8的項目里面有一個代碼用到了javafx&#xff0c;這個我記得是jdk中的包&#xff0c;正常不應該報錯的。然后發現jdk中還真沒有&#xff0c;查了一下是因為版本問題。 Java 8 及之前&#xff1a;Oracle JDK 自帶 JavaFX&#xff0c;OpenJDK 通常不包含Java 9 …

day072-代碼檢查工具-Sonar與maven私服-Nexus

文章目錄0. 老男孩思想-選對池塘釣美人魚1. 代碼回滾方案2. SonarQube2.1 代碼檢查工具2.2 部署sonarqube2.2.1 軟件要求2.2.2 安裝軟件2.2.3 啟動sonar2.2.4 部署插件2.3 sonar檢查java代碼2.3.1 創建sona項目2.3.2 分析java代碼2.3.3 Jenkins結合sonar檢查代碼2.4 sonar檢查非…

【前端基礎】15、列表元素、表格元素、表單元素(注:極其粗略的記載。)

一、列表元素 1、什么是列表元素2、有序列表&#xff08;ol、li&#xff09; ol有序列表 直接子元素只能是li。 li列表中的每一項。3、無序列表&#xff08;ul、li&#xff09; ol無序列表 直接子元素只能是li。 li列表中的每一項。4、定義列表&#xff08;dl、dt、dd&#xff…

IRFBG30PBF Vishay威世MOSFET場效應管

IRFBG30PBF Vishay威世&#xff1a;超快MOSFET 場效應管一、產品定位IRFBG30PBF 是Vishay威世推出的600V/30A N溝道功率MOSFET&#xff0c;采用第五代TrenchFET技術&#xff0c;專為開關電源、電機驅動、新能源逆變器等高功率場景設計。以85mΩ超低導通電阻和超快反向恢復&…

【07-AGI的討論】

AI ANI&#xff1a;artificial narrow intelligence; 如 智能音箱&#xff1b;自動駕駛汽車&#xff0c;網絡搜索&#xff0c;其他用于專業特定事項的工具&#xff1b; AGI&#xff1a;artificial general intelligence; building AI systems that could do anything a typical…

[激光原理與應用-225]:機械 - 3D圖與2D圖各自的作用

在機械設計與加工領域&#xff0c;3D圖和2D圖是兩種核心的工程表達方式&#xff0c;它們在產品設計、制造、裝配及維護等環節中扮演不同角色&#xff0c;具有互補性。以下是它們各自的作用及具體應用場景的詳細解析&#xff1a;一、3D圖的作用1. 直觀展示產品全貌三維可視化&am…

【從零開始java學習|第一篇】java中的名詞概念(JDK、JVM、JRE等等)

目錄 一、核心運行環境三要素&#xff08;JVM/JRE/JDK&#xff09; 二、常用開發指令&#xff08;JDK 自帶工具&#xff09; 三、一些其他概念 四、總結核心邏輯鏈 要入門 Java&#xff0c;理解核心概念之間的關系是基礎。以下是 Java 中最核心的基礎概念、工具及相關名詞的…

UVa12345 Dynamic len(set(a[L:R]))

[TOC](UVa12345 Dynamic len(set(a[L:R]))) 題目鏈接 UVA - 12345 Dynamic len(set(a[L:R])) 題意 有編號從 0 到 n?1 的 n 個數&#xff0c;有兩種操作&#xff1a; Q L R 詢問編號 L 到編號 R?1 的數中有多少個不同的數字。M X Y 將編號為 X 的數字改為 Y。 你的任務就是…

[Ubuntu] VNC連接Linux云服務器 | 實現GNOME圖形化

將桌面環境修改為 GNOME 并通過 VNC 遠程訪問的步驟 & TightVNC 的安裝與配置說明&#xff1a;1. 安裝 GNOME 桌面環境 sudo apt update sudo apt install ubuntu-gnome-desktop -y2. 安裝 TightVNC 服務器 sudo apt install tightvncserver -y3. 初始化 VNC Server 并設置…

進程、網絡通信方法

一、進程間通信(IPC)方法 適用于同一臺主機上的進程間數據交換。 管道(Pipe) 匿名管道:單向通信,僅用于父子進程。 命名管道(FIFO):通過文件系統路徑訪問,支持無親緣關系進程。 消息隊列(Message Queue) 結構化消息(類型+數據),按類型讀取,支持異步通信。…

[激光原理與應用-241]:設計 - 266n皮秒深紫外激光器,哪些因素影響激光器紫外光的輸出功率?

一、短期穩定性266nm皮秒深紫外激光器紫外光輸出功率的穩定性受非線性晶體性能、光學系統設計、熱管理效果、重復頻率與脈沖能量匹配度、環境干擾控制等因素影響&#xff0c;具體分析如下&#xff1a;1. 非線性晶體性能晶體選擇與狀態&#xff1a;BBO&#xff08;偏硼酸鋇&…

Django配置sqllite之外的數據庫

當連接到其他數據庫后端時&#xff0c;如 MariaDB、MySQL、Oracle 或 PostgreSQL&#xff0c;將需要額外的連接參數。請參閱下面的 ENGINE 配置&#xff0c;了解如何指定其他數據庫類型。這個例子是針對 PostgreSQL&#xff1a; 在django項目的settings.py文件里&#xff0c;關…

銀河通用招人形機器人強化學習算法工程師了

人形強化學習算法工程師&#xff08;26屆&#xff09;&#xff08;崗位信息已通過jobleap.cn授權&#xff0c;可在csdn發布&#xff09;銀河通用機器人 北京收錄時間&#xff1a; 2025年08月11日職位描述1. 研發基于深度強化學習的足式機器人運動控制算法&#xff0c;提升機器…

使用MongoDB存儲和計算距離

一、MongoDB 計算距離的優勢 優勢說明原生地理空間索引支持 2dsphere 索引&#xff0c;高效處理地理坐標查詢&#xff08;毫秒級響應&#xff09;。內置地理計算函數提供 $near、$geoWithin、$geoNear 等操作符&#xff0c;無需手動實現復雜計算。高性能基于B樹索引優化&#…

鴻蒙開發-ArkUI中@Type作用詳細解答

在鴻蒙&#xff08;HarmonyOS&#xff09;應用開發中&#xff0c;Type 是 ArkUI 框架中用于 類型定義和類型檢查 的關鍵注解&#xff08;裝飾器&#xff09;。它的主要作用是為自定義組件的屬性提供明確的類型約束&#xff0c;確保數據傳遞的類型安全性。 核心作用解析&#xf…

MCU中的存儲器映射(Memory Map)

MCU中的存儲器映射(Memory Map) 在MCU(微控制器單元)中,存儲器映射(Memory Map)是指將不同類型的存儲器(如Flash、RAM、外設寄存器等)和功能模塊分配到統一的地址空間的過程。這種映射方式使得CPU可以通過訪問特定地址來讀寫數據或控制外設,而無需關心物理存儲介質的…

Rust面試題及詳細答案120道(11-18)-- 控制流與函數

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

數據結構-排序(2)

一、堆排序 &#xff08;借助樹&#xff09;1.利用完全二叉樹構建大頂堆 2.堆頂元素和堆底元素進行交換&#xff0c;堆底元素不再參與構建&#xff0c;剩余元素繼續構建大頂堆3.時間復雜度 O(nlogn)1.完全二叉樹&#xff1a;按照從上到下&#xff0c;從左到右的順序進行排序2.…