代碼隨想錄算法訓練營第60期第五十天打卡

? ? ? ? 大家好,首先感慨一下,時間過的真是快,不知不覺我們的訓練營就已經到第五十天了,首先祝賀自己一直在堅持,今天是我們動態規劃章節的收官之戰,明天我們就會走進一個全新的算法章節單調棧,我們要為我們的動態規劃章節畫上一個完美的句號,那我們就開始我們今天的動態規劃的題目。

第一題對應力扣編號為647的題目回文子串

? ? ? ? 其實大家應該很熟悉什么叫回文子串了,就是倒著讀和正著讀是一樣的,當然很明顯一個字符的字符串當然是回文串,那今天的這道題目是什么意思呢?我們先一起來看一下:

? ? ? ? 其實很明顯題目是要求我們去求回文串的個數,我們就直接考慮使用動態規劃的思路來解決這道題目,當然免不了要使用動規五部曲:

? ? ? ? 第一步確定dp數組以及下標的含義:這道題目就有點不一樣了,我們以前做過的絕大部分題目我們都是題目要求什么我們就定義什么,但是在這里我們如果還要定義dp[i] 為 下標i結尾的字符串有 dp[i]個回文串的話我們就會發現我們壓根找不到遞推關系,這樣就不好了,沒有遞推關系我們可怎么解決這道題目?大家其實想想我們回文串dp[i]與dp[i-1]與dp[i+1]是否存在什么關系嗎?好像是沒有的,它們壓根可以表示任意一個字符,而且還有回文串的長度也是不確定的,因此我們這時候去看回文串的關系示意圖:

? ? ? ? 我們的確使用一個變量跟本表示不了回文字符串,因此我們就需要考慮使用類似于雙指針的思想,其實我們在寫判斷回文字符串的函數的時候我們也是會考慮使用雙指針的思想來判斷,因此我們可以這樣判斷回文串了,因此我們就可以找到合適的定義dp數組的方法,我們就可以這樣定義:布爾類型的dp[i][j]:表示區間范圍[i,j] (注意是左閉右閉)的子串是否是回文子串,如果是dp[i][j]為true,否則為false。

? ? ? ?第二步確定遞推公式,在確定遞推公式時,就要分析如下幾種情況。其實主要是兩種情況,第一種情況當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。以上所有的情況都必不可少。

? ? ? 第三步就是初始化dp數組,dp[i][j]可以初始化為true么? 當然不行,怎能剛開始就全都匹配上了。因此我們需要把dp[i][j] = false才可以。

? ? ? 第四步確定遍歷順序,這個有點意思,我們還是得看一下dp數組的示意圖:

? ? ? ? 因此我們如果這矩陣是從上到下,從左到右遍歷,那么會用到沒有計算過的dp[i + 1][j - 1],也就是根據不確定是不是回文的區間[i+1,j-1],來判斷了[i,j]是不是回文,那結果一定是不對的。我們需要一定要從下到上,從左到右遍歷,這樣保證dp[i + 1][j - 1]都是經過計算的

? ? ? ? 經過上述分析,我們就可以給出本題的解題代碼:

class Solution {
public:int countSubstrings(string s) {//初始化dp數組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;}
};

? ? ? ? 這道題其實有點反常規操作,當然理解遍歷順序與定義dp數組的思想是關鍵,我們這道題就分享到這里,我們繼續我們的下一道題目。

第二題對應力扣編號為516的題目最長的回文子序列

? ? ? ?這道題與上一道題目應該是類似的,還是回文子串的問題,我們先看一下題目要求:

? ? ? ? 我們應該是返回最長的回文子序列的長度,而且其實我們是可以對原字符串進行刪除操作的,其實就是告訴我們我們找到的回文字符串未必是連續的,我們就使用動規五部曲來解決這道題目:

? ? ? 第一步確定dp數組以及下標的含義,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]),其實我們還是進行了刪除操作,感覺與前面的題目思路都有相似的地方,理解dp數組的含義很重要。

? ? ? 第三步是初始化dp數組,首先要考慮當i 和j 相同的情況,從遞推公式:dp[i][j] = dp[i + 1][j - 1] + 2; 可以看出 遞推公式是計算不到 i 和j相同時候的情況。其實我們需要考慮的是當i與j相同,那么dp[i][j]一定是等于1的,其他情況dp[i][j]初始為0就行,這樣遞推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); 中dp[i][j]才不會被初始值覆蓋。

? ? ? 第四步就是確定遍歷順序,大家看下面的圖:?

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

? ? ?綜合上述分析我們就可以給出答案:

class Solution {
public:int longestPalindromeSubseq(string s) {//定義dp數組vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));//dp數組的初始化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];}
};

動態規劃總結篇

? ? ? ? 到這里我們就完成了動態規劃的所有題目,其實動態規劃的題目類型很多,我們刷了不少類型,我們也深刻理解了動規五部曲在解題中的巧妙使用,如果遇到問題大家可以這樣想:我們如果想不清楚dp數組的具體含義,遞歸公式從何談起,甚至初始化的時候就寫錯了。如果看過背包系列,特別是完全背包,那么兩層for循環先后順序絕對可以搞懵很多人,反而遞歸公式是簡單的。背包問題要注意區分,我們的遍歷順序很重要,希望大家可以好好努力,多去理解,掌握任何一種算法都不簡單,更何況是動態規劃這種比較難的題目,我們今天的分享就到這里,我們明天的單調棧見!

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

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

相關文章

如何發布npm包?

如何發布npm包&#xff1f; 1. 注冊賬號[npm官網](https://www.npmjs.com/)2. 檢查 npm 源是否在官方 npm 倉庫&#xff0c;如果不在&#xff0c;進行切換3. 檢查4. 打包配置5. 發布6. 使用錯誤&#xff1a;版本更新命令 1. 注冊賬號npm官網 2. 檢查 npm 源是否在官方 npm 倉庫…

AI工具使用的最佳實踐,如何通過AI工具提高創作與工作效率

隨著科技的迅猛發展&#xff0c;人工智能&#xff08;AI&#xff09;已從遙不可及的未來構想&#xff0c;轉變為廣泛應用于各行業的實用工具。AI不僅在內容創作、設計、寫作等領域展現出巨大潛力&#xff0c;還通過自動化和智能化顯著提升了工作效率。本文將深入探討如何通過選…

漏洞Reconfigure the affected application to avoid use of weak cipher suites. 修復方案

修復方案&#xff1a;禁用弱加密套件&#xff08;Weak Cipher Suites&#xff09; 1. 確認當前使用的加密套件 在修復前&#xff0c;先檢查應用程序或服務器當前支持的加密套件&#xff1a; OpenSSL (適用于HTTPS/TLS服務)openssl ciphers -v ALL:COMPLEMENTOFALL | sortNgi…

AI對軟件工程的影響及未來發展路徑分析報告

目錄 第一部分&#xff1a;引言 研究背景與意義 報告框架與方法論 第二部分&#xff1a;AI對不同行業軟件工程的影響分析 數字化行業 制造業 零售業 工業領域 第三部分&#xff1a;大廠AI軟件工程實踐案例分析 微軟 谷歌 阿里巴巴 華為 第四部分&#xff1a;未來…

WSL里執行python深度學習的一些方法記錄

安裝anaconda3&#xff1a; 可以直接從 Download Now | Anaconda 中下載&#xff0c;然后拷貝到WSL環境的某個目錄&#xff0c;執行 bash xxxxxxx.sh 即可安裝。 啟動jupyter notebook&#xff1a; 先conda activate 當前環境&#xff0c;然后pip install jupyter 此時&am…

使用 SpyGlass Power Verify 解決方案中的規則

本節提供了關于使用 SpyGlass Power Verify 解決方案 的相關信息。內容組織如下: SpyGlass Power Verify 簡介運行 SpyGlass Power Verify 解決方案在 SpyGlass Power Verify 解決方案中評估結果SpyGlass Power Verify 解決方案中的參數SpyGlass Power Verify 報告1 SpyGlass …

spring4第3課-ioc控制反轉-詳解依賴注入的4種方式

1&#xff0c;屬性注入&#xff1b; 2&#xff0c;構造函數注入&#xff1b;(通過類型&#xff1b;通過索引&#xff1b;聯合使用) 3&#xff0c;工廠方法注入&#xff1b;(非靜態工廠&#xff0c;靜態工廠) 4&#xff0c;泛型依賴注入&#xff1b;(Spring4 整合 Hibernate4…

使用Rust和并發實現一個高性能的彩色分形圖案渲染

分形與 Mandelbrot Mandelbrot 集 (Mandelbrot Set) 是復數平面上一個點的集合,以數學家 Benot Mandelbrot 的名字命名。它是最著名的分形之一。一個復數 c 是否屬于 Mandelbrot 集,取決于一個簡單的迭代過程: z n + 1 = z n 2 + c z_{n+1}=z_{n}^2+c zn+1?=zn2?+c 如果…

微信小程序的軟件測試用例編寫指南及示例--性能測試用例

以下是針對微信小程序的性能測試用例補充,結合代碼邏輯和實際使用場景,從加載性能、渲染性能、資源占用、交互流暢度等維度設計測試點,并標注對應的優化方向: 一、加載性能測試用例 測試項測試工具/方法測試步驟預期結果優化方向冷啟動加載耗時微信開發者工具「性能」面板…

行為型:觀察者模式

目錄 1、核心思想 2、實現方式 2.1 模式結構 2.2 實現案例 3、優缺點分析 4、適用場景 5、注意事項 1、核心思想 目的&#xff1a;針對被觀察對象與觀察者對象之間一對多的依賴關系建立起一種行為自動觸發機制&#xff0c;當被觀察對象狀態發生變化時主動對外發起廣播&…

t009-線上代駕管理系統

項目演示地址 摘 要 使用舊方法對線上代駕管理系統的信息進行系統化管理已經不再讓人們信賴了&#xff0c;把現在的網絡信息技術運用在線上代駕管理系統的管理上面可以解決許多信息管理上面的難題&#xff0c;比如處理數據時間很長&#xff0c;數據存在錯誤不能及時糾正等問題…

LVS-NAT 負載均衡群集

目錄 簡介 一、LVS 與群集技術基礎 1.1 群集技術概述 1.2 負載均衡群集的分層結構 1.3 負載均衡工作模式 二、LVS 虛擬服務器核心組件與配置 2.1 LVS 內核模塊與管理工具 2.2 負載調度算法解析 2.3 ipvsadm 管理工具實戰 三、NFS 共享存儲服務配置 3.1 NFS 服務基礎…

LLaMaFactory - 支持的模型和模板 常用命令

一、 環境準備 激活LLaMaFactory環境&#xff0c;進入LLaMaFactory目錄 cd LLaMA-Factoryconda activate llamafactory 下載模型 #模型下載 from modelscope import snapshot_download model_dir snapshot_download(Qwen/Qwen2.5-0.5B-Instruct) 二、啟動一個 Qwen3-0.6B…

EDW2025|數據治理的神話破除——從誤區到現實

在當今數據驅動的世界中&#xff0c;數據治理已成為企業成功的關鍵因素。然而&#xff0c;許多組織在實施數據治理時&#xff0c;常常被一些常見的誤區所困擾。本文將逐一破除這些誤區&#xff0c;揭示數據治理的真實面貌。 誤區一&#xff1a;你需要一個大的預算&#xff01;…

AIGC與影視制作:技術革命、產業重構與未來圖景

文章目錄 一、AIGC技術全景&#xff1a;從算法突破到產業賦能1. **技術底座&#xff1a;多模態大模型的進化路徑**2. **核心算法&#xff1a;從生成對抗網絡到擴散模型的迭代** 二、AIGC在影視制作全流程中的深度應用1. **劇本創作&#xff1a;從“靈感枯竭”到“創意井噴”**2…

ReactJS 中的 JSX工作原理

文章目錄 前言? 1. JSX 是什么&#xff1f;&#x1f527; 2. 編譯后的樣子&#xff08;核心機制&#xff09;&#x1f9f1; 3. React.createElement 做了什么&#xff1f;&#x1f9e0; 4. JSX 與組件的關系&#x1f504; 5. JSX 到真實 DOM 的過程&#x1f4d8; 6. JSX 與 Fr…

Spring Advisor增強規則實現原理介紹

Spring Advisor增強規則實現原理介紹 一、什么是 Advisor&#xff1f;1. Advisor 的定義與本質接口定義&#xff1a; 2. Advisor 的核心作用統一封裝切點與通知構建攔截器鏈的基礎實現增強邏輯的靈活組合 二. Sprin當中的實現邏輯1 Advisor 接口定義2 PointcutAdvisor 接口定義…

小程序32-簡易雙向數據綁定

在WXML中&#xff0c;普通屬性的綁定是單向的&#xff0c;例如:<input value"{{value}}" /> 如果希望用戶輸入數據的同時改變data中的數據&#xff0c;可以借助簡易雙向綁定機制。在對應屬性之前添加model:前綴即可: 例如<input model:value"{{value}…

Nginx網站服務:從入門到LNMP架構實戰

&#x1f3e1;作者主頁&#xff1a;點擊&#xff01; Nginx-從零開始的服務器之旅專欄&#xff1a;點擊&#xff01; &#x1f427;Linux高級管理防護和群集專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2025年5月30日14點22分 前言 說起Web服務器&#xff0c…

【maker-pdf 文檔文字識別(包含ocr),安裝使用完整教程】

安裝環境 conda create -n maker-pdf python3.12 conda activate marker-pdf pip install modelscope pip install marker-pdf -U下載模型 from modelscope import snapshot_downloadmodel_root "models" snapshot_download("Lixiang/marker-pdf", loca…