動態規劃Day7學習心得

今天給動態規劃掃個尾,還有兩題。

第一道:647. 回文子串 - 力扣(LeetCode)

暴力解法

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

動態規劃

動規五部曲:

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

本題如果定義,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]相等時,這就復雜一些了,有如下三種情況

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

以上三種情況分析完了,那么遞歸公式如下:

if (s[i] == s[j]) {if (j - i <= 1) { // 情況一 和 情況二result++;dp[i][j] = true;} else if (dp[i + 1][j - 1]) { // 情況三result++;dp[i][j] = true;}
}

result就是統計回文子串的數量。

注意這里沒有列出當s[i]與s[j]不相等的時候,因為在下面dp[i][j]初始化的時候,就初始為false。

dp數組如何初始化

dp[i][j]可以初始化為true么? 當然不行,怎能剛開始就全都匹配上了。

所以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],也就是根據不確定是不是回文的區間[i+1,j-1],來判斷了[i,j]是不是回文,那結果一定是不對的。

所以一定要從下到上,從左到右遍歷,這樣保證dp[i + 1][j - 1]都是經過計算的

C++代碼如下:

class Solution {
public:int countSubstrings(string s) {vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int result = 0;for (int i = s.size() - 1; i >= 0; i--) {  // 注意遍歷順序for (int j = i; j < s.size(); j++) {if (s[i] == s[j]) {if (j - i <= 1) { // 情況一 和 情況二result++;dp[i][j] = true;} else if (dp[i + 1][j - 1]) { // 情況三result++;dp[i][j] = true;}}}}return result;}
};

然后看第二道:516. 最長回文子序列 - 力扣(LeetCode)

回文子串是要連續的,回文子序列可不是連續的!

動規五部曲分析如下:

確定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]看看哪一個可以組成最長的回文子序列。

加入s[j]的回文子序列長度為dp[i + 1][j]。

加入s[i]的回文子序列長度為dp[i][j - 1]。

那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

代碼如下:

if (s[i] == s[j]) {dp[i][j] = dp[i + 1][j - 1] + 2;
} else {dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}

dp數組如何初始化

首先要考慮當i 和j 相同的情況,從遞推公式:dp[i][j] = dp[i + 1][j - 1] + 2; 可以看出 遞推公式是計算不到 i 和j相同時候的情況。

所以需要手動初始化一下,當i與j相同,那么dp[i][j]一定是等于1的,即:一個字符的回文子序列長度就是1。

其他情況dp[i][j]初始為0就行,這樣遞推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); 中dp[i][j]才不會被初始值覆蓋。

vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
for (int i = 0; i < s.size(); i++) dp[i][i] = 1;

確定遍歷順序

從遞歸公式中,可以看出,dp[i][j] 依賴于 dp[i + 1][j - 1] ,dp[i + 1][j] 和 dp[i][j - 1],

所以遍歷i的時候一定要從下到上遍歷,這樣才能保證下一行的數據是經過計算的

j的話,可以正常從左向右遍歷。

C++代碼如下:

class Solution {
public:int longestPalindromeSubseq(string s) {vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));for (int i = 0; i < s.size(); i++) dp[i][i] = 1;for (int i = s.size() - 1; i >= 0; i--) {for (int j = i + 1; j < s.size(); j++) {if (s[i] == s[j]) {dp[i][j] = dp[i + 1][j - 1] + 2;} else {dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);}}}return dp[0][s.size() - 1];}
};

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

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

相關文章

SpringCloud實戰:機器人對戰系統架構

基于Spring Cloud的機器人對戰 以下是基于Spring Cloud的機器人對戰實例相關案例和技術實現方向的整理,涵蓋微服務架構設計、通信機制及典型應用場景: 分布式對戰系統架構 采用Spring Cloud Alibaba+Nacos實現服務注冊與發現,每個機器人實例作為獨立微服務部署。通過Open…

LLM 核心能力解構與項目實踐指南

大語言模型&#xff08;LLM&#xff09;的爆發式發展&#xff0c;本質上是其核心能力在產業場景中的規模化驗證。作為技術博主&#xff0c;本文將系統拆解 LLM 的六大核心能力&#xff0c;結合工業級項目案例&#xff0c;提供從能力映射到工程實現的完整技術路徑&#xff0c;并…

retro-go 1.45 編譯及顯示中文

最近做了個使用 retro-go 的開源掌機 基于ESP32-S3的C19掌機&#xff08;適配GBC外殼&#xff09; - 立創開源硬件平臺 &#xff0c;做完后用提供的固件發現屏幕反顯了&#xff0c;估計是屏幕型號不太對&#xff0c;隨即自己拉 retro-go 官方庫來編譯&#xff0c;拉取的最新的 …

中州養老項目:Mybatis自動填充攔截器

功能:在新增護理項目的時候,創建人,創建時間和修改時間字段會自動攔截填充,這些公共字段可以省去我們一個一個處理的麻煩依靠:AutoFillInterceptor攔截器,MybatisConfig配置類第一步:我們需要借助一個MybatisConfig,configuration標志著這是一個配置類,我們需要將autoFillInter…

[創業之路-527]:什么是產品技術成熟度曲線?

產品技術成熟度曲線&#xff08;Gartner Hype Cycle&#xff09;是由全球知名咨詢機構Gartner提出的工具&#xff0c;用于可視化展示新興技術從誕生到成熟的發展軌跡&#xff0c;以及市場對其預期和實際采用趨勢的變化。該曲線通過五個階段刻畫技術生命周期&#xff0c;幫助企業…

VScode對Ubuntu用root賬號進行SSH遠程連接開發

由于linux服務器大部分都是基于命令行的操作&#xff0c;缺乏比較方便好用的編輯工具&#xff0c;對于經常在linux服務器上做開發的同學來說直接在服務器上進行開發或配置文件的修改還不是特別的方便。雖然linux上有vi或vim比起圖形化的編輯工具體驗感還是不是很好。作為程序員…

【物聯網】基于樹莓派的物聯網開發【20】——樹莓派控制DHT11溫濕度傳感器實戰

傳感器概述 DHT11是一款有已校準數字信號輸出的溫濕度傳感器。 其精度濕度5%RH&#xff0c; 溫度2℃&#xff0c;量程濕度20-90%RH&#xff0c; 溫度0~50℃。分為3個接口&#xff0c;分別為&#xff1a;VCC, DATA, GND。 產品圖片主要用途 檢測環境溫濕度 GPIO控制DHT11溫濕度傳…

AI原生數據庫:告別SQL的新時代來了?

在2025年的今天&#xff0c;生成式AI的浪潮正以前所未有的力量重塑著各行各業。從代碼生成到藝術創作&#xff0c;大型語言模型&#xff08;LLM&#xff09;的能力邊界不斷被拓寬。現在&#xff0c;這股浪潮正涌向信息技術領域最古老、最核心的基石之一&#xff1a;數據庫。一個…

題單【模擬與高精度】

P1042 [NOIP 2003 普及組] 乒乓球 P1042 [NOIP 2003 普及組] 乒乓球 - 洛谷 #include<bits/stdc.h> using namespace std;char C; string S; int n,A,B;void Work(int Lim) {for(char i:S){if(iW) A;if(iL) B;if(max(A,B)>Lim && abs(A-B)>2){cout<<…

數據結構學習基礎和從包裝類緩存到泛型擦除的避坑指南

目錄 1.數據結構的概念和算法 1.1 數據結構的概念 1.2 數據結構的集合框架 1.3 算法 1.3.1 時間復雜度 1.3.2 空間復雜度 2.包裝類 2.1 為什么需要包裝類&#xff1f; 2.2 裝箱和拆箱 3. 初識泛型 3.1 認識泛型 3.2 泛型類的使用 3.3 泛型的編譯 3.4 通配符 3.4.1 …

網絡安全基礎知識【6】

什么是防火墻1.防火墻指的是一個由軟件和硬件設備組合而成、在內部網和外部網之間、 專用網與公共網之間的界面上構造的保護屏障 2.防火墻實際上是一種隔離技術 3.防火墻重要的特征是增加了區域的概念防火墻的定義 隔離可信與不可信網絡的設備/軟件&#xff0c;基于策略控制流量…

Apache Doris數據庫——大數據技術

Apache Doris一、簡介1.1、Apache Doris簡介1.2、Apache Doris 與傳統大數據架構相比1.3、doris是java團隊掌控大數據能力最優選擇1.4、 OLTP&#xff08;在線事務處理&#xff09; 與 OLAP&#xff08;在線分析處理&#xff09;1.5、發展歷程1.6、應用現狀1.7、整體架構1.7.1、…

Conda和pip的使用記錄

Conda和pip的使用記錄一、創建新的 Conda 環境二、激活環境三、安裝其他包&#xff08;可選&#xff09;四、查看已有環境五、刪除環境&#xff08;可選&#xff09;?? Conda 下載緩慢的解決方案&#xff08;推薦使用國內鏡像&#xff09;&#x1f527; 方法一&#xff1a;**…

詳解Python標準庫之互聯網數據處理

詳解Python標準庫之互聯網數據處理 在互聯網時代&#xff0c;數據的產生、傳輸和處理無處不在。從電子郵件的收發到 API 接口的數據交換&#xff0c;從二進制數據的編碼到 MIME 類型的識別&#xff0c;Python 標準庫提供了一整套強大的工具集&#xff0c;幫助開發者輕松應對各種…

適 配 器 模 式

前陣子&#xff0c;筆者在網上淘來一個二手顯示屏來搭配我裝好的主機&#xff0c;但是送到手上后我卻找不到電源適配器的蹤跡。于是我就在家找了根電源線接上了顯示屏&#xff0c;倒是能亮&#xff0c;就是屏幕閃得和機關槍似的。這是因為我的顯示屏需要12V的供電&#xff0c;我…

智慧零售商品識別準確率↑32%:陌訊多模態融合算法實戰解析

原創聲明本文為原創技術解析&#xff0c;核心技術參數與架構設計引用自《陌訊技術白皮書》&#xff0c;禁止任何形式的未經授權轉載。一、行業痛點&#xff1a;智慧零售的 "看得見的障礙"在智慧零售場景中&#xff0c;從自助結算終端到智能貨架管理&#xff0c;計算機…

Linux系統編程-gcc(黑馬筆記)

1 gcc的編譯流程gcc編譯的整個過程并且整個過程下來的每個過程。并且給出了每個階段產物和gcc命令。1.1 數據段合并其實就是因為“塊” 一次是讀多個字節而不是一個字節&#xff0c;所以會將一些地址段合并從而提升效率1.2 地址回填這張圖也有些問題&#xff0c;正確的結論是:地…

Git踩坑

文章目錄前言?問題分析&#xff1a;為什么你的提交會“覆蓋”別人的代碼&#xff1f;? 正確的代碼提交流程&#xff08;結合你原文的說明&#xff09;**1. 確認自己在正確的分支上****2. 從主開發分支&#xff08;如 dev&#xff09;拉取最新代碼并合并****3. 解決沖突&#…

sqli-labs:Less-20關卡詳細解析

1. 思路&#x1f680; 本關的SQL語句為&#xff1a; $sql"SELECT * FROM users WHERE username$cookee LIMIT 0,1";注入類型&#xff1a;字符串型&#xff08;單引號包裹&#xff09;、GET操作提示&#xff1a;參數需以閉合關鍵參數&#xff1a;cookee php輸出語句…

基于LevitUnet的超聲圖像分割

完整項目包獲取&#xff1a;點擊文末名片本項目旨在開發一個基于深度學習的圖像分割模型&#xff0c;專門用于處理醫學或遙感領域的圖像數據&#xff08;以 TIFF 格式存儲&#xff09;。通過結合 LeViT&#xff08;基于 Vision Transformer 的輕量模型&#xff09;和 U-Net 架構…