算法訓練 | 動態規劃Part10 | 300.最長遞增子序列、674.最長連續遞增序列、718.最長重復子數組

目錄

300.最長遞增子序列

動態規劃法

674.最長連續遞增序列

動態規劃法

718.最長重復子數組

動態規劃法


300.最長遞增子序列

  • 題目鏈接:300. 最長遞增子序列 - 力扣(LeetCode)

  • 文章講解:代碼隨想錄

動態規劃法
  • “子序列是由數組派生而來的序列,刪除(或不刪除)數組中的元素而不改變其余元素的順序”。

  • 解題思路

    • 子序列問題是動態規劃解決的經典問題,當前下標i的遞增子序列長度,其實和i之前的下表j的子序列長度有關系.

  • 解題步驟

    • dp[i]的定義:dp[i]表示i之前包括i的以nums[i]結尾的最長遞增子序列的長度

    • 狀態轉移方程:位置i的最長升序子序列等于j從0到i-1各個位置的最長升序子序列 + 1 的最大值。所以:if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);注意這里不是要dp[i] 與 dp[j] + 1進行比較,而是我們要取dp[j] + 1的最大值。

    • dp[i]的初始化:每一個i,對應的dp[i](即最長遞增子序列)起始大小至少都是1.

    • 確定遍歷順序:dp[i] 是有0到i-1各個位置的最長遞增子序列 推導而來,那么遍歷i一定是從前向后遍歷。j其實就是遍歷0到i-1,那么是從前到后,還是從后到前遍歷都無所謂,只要吧 0 到 i-1 的元素都遍歷了就行了。 所以默認習慣 從前向后遍歷。

    • 舉例推導dp數組:

  • 代碼注意

    • dp[j] + 1不是和dp[i]比,而是找最大的dp[j] + 1

  • 代碼一:動態規劃

class Solution {
public:int lengthOfLIS(vector<int>& nums) {if (nums.size() <= 1) return nums.size();vector<int> dp(nums.size(), 1);int result = 0;for (int i = 1; i < nums.size(); i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);}if (dp[i] > result) result = dp[i]; // 取長的子序列}return result;}
};

674.最長連續遞增序列

  • 題目鏈接:674. 最長連續遞增序列 - 力扣(LeetCode)

  • 文章講解:代碼隨想

動態規劃法
  • 解題思路

    • 本題相對于動態規劃:300.最長遞增子序列 (opens new window)最大的區別在于“連續”。本題要求的是最長連續遞增序列

  • 解題步驟

    • 確定dp數組(dp table)以及下標的含義:dp[i]:以下標i為結尾的連續遞增的子序列長度為dp[i]。注意這里的定義,一定是以下標i為結尾,并不是說一定以下標0為起始位置。

    • 確定遞推公式:如果 nums[i] > nums[i - 1],那么以 i 為結尾的連續遞增的子序列長度 一定等于 以i - 1為結尾的連續遞增的子序列長度 + 1 。即:dp[i] = dp[i - 1] + 1;注意這里就體現出和動態規劃:300.最長遞增子序列 (opens new window)的區別!為本題要求連續遞增子序列,所以就只要比較nums[i]與nums[i - 1],而不用去比較nums[j]與nums[i] (j是在0到i之間遍歷)。既然不用j了,那么也不用兩層for循環,本題一層for循環就行,比較nums[i] 和 nums[i - 1]。

    • dp數組如何初始化:以下標i為結尾的連續遞增的子序列長度最少也應該是1,即就是nums[i]這一個元素。所以dp[i]應該初始1;

    • 確定遍歷順序:從遞推公式上可以看出, dp[i + 1]依賴dp[i],所以一定是從前向后遍歷。

    • 舉例推導dp數組:

  • 代碼一:動態規劃

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {if (nums.size() == 0) return 0;int result = 1;vector<int> dp(nums.size() ,1);for (int i = 1; i < nums.size(); i++) {if (nums[i] > nums[i - 1]) { // 連續記錄dp[i] = dp[i - 1] + 1;}if (dp[i] > result) result = dp[i];}return result;}
};

718.最長重復子數組

  • 題目鏈接:718. 最長重復子數組 - 力扣(LeetCode)

  • 文章講解:代碼隨想錄

動態規劃法
  • 解題思路

    • 注意題目中說的子數組,其實就是連續子序列。要求兩個數組中最長重復子數組,如果是暴力的解法 只需要先兩層for循環確定兩個數組起始位置,然后再來一個循環可以是for或者while,來從兩個起始位置開始比較,取得重復子數組的長度。本題其實是動規解決的經典題目,用二維數組可以記錄兩個字符串的所有比較情況,這樣就比較好推 遞推公式了。

  • 解題步驟

    • 確定dp數組(dp table)以及下標的含義:dp[i][j] :以下標i - 1為結尾的A,和以下標j - 1為結尾的B,最長重復子數組長度為dp[i][j]。 (特別注意: “以下標i - 1為結尾的A” 標明一定是 以A[i-1]為結尾的字符串 。其實dp[i][j]的定義也就決定著,我們在遍歷dp[i][j]的時候i 和 j都要從1開始。

    • 確定遞推公式:根據dp[i][j]的定義,dp[i][j]的狀態只能由dp[i - 1][j - 1]推導出來。即當A[i - 1] 和B[j - 1]相等的時候,dp[i][j] = dp[i - 1][j - 1] + 1;根據遞推公式可以看出,遍歷i 和 j 要從1開始!

    • dp數組如何初始化:根據dp[i][j]的定義,dp[i][0] 和dp[0][j]其實都是沒有意義的!但dp[i][0] 和dp[0][j]要初始值,因為 為了方便遞歸公式dp[i][j] = dp[i - 1][j - 1] + 1;所以dp[i][0] 和dp[0][j]初始化為0。舉個例子A[0]如果和B[0]相同的話,dp[1][1] = dp[0][0] + 1,只有dp[0][0]初始為0,正好符合遞推公式逐步累加起來。

    • 確定遍歷順序:外層for循環遍歷A,內層for循環遍歷B。同時題目要求長度最長的子數組的長度。所以在遍歷的時候順便把dp[i][j]的最大值記錄下來。

    • 舉例推導dp數組:

  • 代碼一:動態規劃

class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp (nums1.size() + 1, vector<int>(nums2.size() + 1, 0));int result = 0;for (int i = 1; i <= nums1.size(); i++) {for (int j = 1; j <= nums2.size(); j++) {if (nums1[i - 1] == nums2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;}if (dp[i][j] > result) result = dp[i][j];}}return result;}
};

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

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

相關文章

基于java語言+springboot技術架構開發的 互聯網智能3D導診系統源碼支持微信小程序、APP 醫院AI智能導診系統源碼

基于java語言springboot技術架構開發的 互聯網智能3D導診系統源碼支持微信小程序、APP 醫院AI智能導診系統源碼 一、智慧導診系統開發原理 導診系統從原理上大致可分為基于規則模板和基于數據模型兩類。 1、基于規則推理的方法通過人工建立癥狀、疾病和科室之間的對應規則實現…

Java反射API詳解與應用場景

一、Java反射API簡介: 一、什么是反射: 反射是一種強大的工具,它允許我們在運行時檢查類、方法和字段的信息,甚至允許我們動態的調用特定類的方法或改變字段的值。編程語言中的反射機制通常用于從類、對象或方法中檢索元數據,或者更特別的說,從代碼本身中獲取信息。這就…

【51單片機入門】點亮數碼管

文章目錄 前言仿真圖如何去繪制一個數字示例代碼選擇某個數碼管顯示某個數字 示例代碼總結 前言 在嵌入式系統的世界中&#xff0c;單片機扮演著至關重要的角色。51單片機&#xff0c;作為最早的微控制器之一&#xff0c;至今仍被廣泛應用在各種設備中。本文將介紹如何使用51單…

幾種linux開機自啟腳本的方法

幾種linux開機自啟腳本的方法 1. 腳本添加到init.d目錄中2. 創建服務service&#xff08;推薦&#xff09;3. /etc/profile & /etc/profile.d&#xff08;不推薦&#xff09;4. /etc/rc.local 本文以啟動jenkins節點為例&#xff0c;需要持久連接&#xff0c;實現開機自啟 …

js或ts中對象如何循環遍歷獲取名字和值

數組循環有多種方法&#xff0c;但是對象循環還是會遇到一些問題 分開獲取key或value let names{name:kaka,age:12}獲取key值代碼&#xff1a; Object.keys(names).forEach(name>{console.log(name) })結果&#xff1a; 獲取value值代碼&#xff1a; Object.values(name…

多地高溫持續“熱力”爆表 約克VRF中央空調帶你清涼舒爽一夏

“出門5分鐘&#xff0c;流汗2小時”,夏季高溫天氣&#xff0c;怎一個“熱”字了得&#xff1f;6月以來&#xff0c;我國多地迎來高溫“炙烤”&#xff0c;全國出現40℃以上高溫的范圍持續增加&#xff0c;隨著中央氣象臺高溫預警持續拉響&#xff0c;人們都很納悶&#xff1a;…

谷歌瀏覽器報錯ERR_UNSAFF_PORT原因分析

部署了個測試靜態頁&#xff0c;用了10080端口。curl訪問沒問題&#xff0c;chrome瀏覽器訪問報錯 ERR_UNSAFF_PORT 查了一下&#xff0c;google對于部分端口在客戶端是直接攔截的。請求都不會到服務器 定義在這里 谷歌官網源碼&#xff1a;chromium.googlesource.com git…

Android 大話binder通信

戳藍字“牛曉偉”關注我哦&#xff01; 用心堅持輸出易讀、有趣、有深度、高質量、體系化的技術文章 由于 Android 大話binder通信(上) 和 Android 大話binder通信(下) 分為兩篇閱讀體驗不好&#xff0c;顧合并為一篇。 本文摘要 用故事的方式把binder通信的整個過程都描述…

【408考點之數據結構】棧:定義、特點、基本操作與應用

棧&#xff1a;定義、特點、基本操作與應用 棧是一種重要的線性數據結構&#xff0c;廣泛應用于計算機科學和編程中。本文將介紹棧的定義、特點、基本操作以及常見應用。 棧的定義 棧&#xff08;Stack&#xff09;是一種特殊的線性表&#xff0c;只允許在表的一端進行插入和…

TFMath Caculator:一個簡單的Java AWT計算器

目錄 背景&#xff1a; 代碼展示: 代碼解析: 輸出結果: 總結: 背景&#xff1a; 使用Java AWT(Abstract Window Toolkit)庫創建的簡單計算器應用-TFMath Calculator。這個計算器允許用戶輸入兩個數字&#xff0c;點擊號按鈕后&#xff0c;計算器會計算這兩個數字的和&…

在文件末尾添加以下行來添加CRAN鏡像(適合你的Ubuntu版本,例如focal):添加的是ubuntu16.04版本

ChatGPT 如果你的Ubuntu版本是16.04&#xff08;Xenial Xerus&#xff09;&#xff0c;則應該使用適合該版本的CRAN鏡像。下面是具體的步驟&#xff1a; 在Ubuntu 16.04上更新R到較新版本 添加CRAN鏡像&#xff1a; 打開終端并編輯APT源列表文件&#xff1a; bash 復制代碼 …

計算機網絡之OSI七層體系結構

目錄 1.物理層 1.1物理層組成 1.2物理層功能 1.3物理層服務 1.4物理層標準 1.5物理層接口 2.數據鏈路層 2.1基于物理層的問題 2.2數據鏈路層功能 2.3數據鏈路層服務 2.4數據鏈路層協議 3.網絡層 3.1基于DL層的問題 3.2網絡層功能 3.3網絡層服務 3.4網絡層協議 …

Django 靚號管理系統:實現登錄功能

本文將詳細介紹如何在 Django 靚號管理系統中實現登錄功能,包括用戶認證、驗證碼生成、以及中間件的使用。我們將逐步展示所有相關代碼,并附帶詳細注釋。 1. 項目結構 首先,讓我們看一下項目的基本結構: number ├── manage.py ├── monaco.ttf ├── number │ …

Linux下的SSH詳解及Ubuntu教程

前言 SSH&#xff08;Secure Shell&#xff09;是一種用于計算機之間安全通信的協議&#xff0c;廣泛應用于遠程登錄、系統管理和文件傳輸等場景。本文將詳細介紹SSH在Linux系統&#xff08;特別是Ubuntu&#xff09;下的使用&#xff0c;包括安裝、配置、密鑰管理和常見應用&…

怎么加快音頻播放速度?加快音頻播放器的四種方法介紹

怎么加快音頻播放速度&#xff1f;許多音樂愛好者對各種類型的歌曲充滿了熱情&#xff0c;這些歌曲節奏輕快或者緩慢不一&#xff0c;但通常默認的播放速度都是一倍速。有時候&#xff0c;一些旋律悠揚的曲子可能聽起來有些慢&#xff0c;這時候一些朋友可能想要嘗試加快節奏&a…

easyquotation獲取港股的bug

easyquotation&#xff1a;實時股票數據獲取 easyquotation庫&#xff0c;是一個非常好用的實時股票數據獲取庫&#xff0c;可以實時獲取新浪、騰訊的免費股票行情&#xff0c;集思路的分級基金行情 安裝 項目地址&#xff1a;https://github.com/shidenggui/easyquotation.…

鴻蒙開發 之 健康App案例

1.項目介紹 該項目是記錄用戶日常飲食情況&#xff0c;以及針對不同食物攝入營養不同會有對應的營養攝入情況和日常運動消耗情況&#xff0c;用戶可以自己添加食品以及對應的熱量。 1.1登陸頁 1.2飲食統計頁 1.3 食物列表頁 2.登陸頁 2.1自定義彈框 import preferences from oh…

IP地址查詢和代理服務器:雙重保護隱私

隨著網絡應用的日益普及&#xff0c;我們的個人信息和數據安全面臨前所未有的挑戰。在此背景下&#xff0c;IP地址查詢和代理服務器成為保護個人隱私和網絡安全的兩大關鍵工具。本文將從IP地址查詢的原理和應用出發&#xff0c;深入剖析代理服務器在網絡隱私保護中的作用&#…

掌握批處理的高級技巧:使用正則表達式

掌握批處理的高級技巧&#xff1a;使用正則表達式 在Windows批處理腳本編寫中&#xff0c;正則表達式是一個強大的工具&#xff0c;它可以幫助我們進行復雜的字符串匹配和處理。雖然批處理腳本本身并不直接支持正則表達式&#xff0c;但我們可以通過一些技巧和外部工具來實現正…

AI視頻教程下載-數據分析中的提示工程:Python、Pandas、ChatGPT

Prompt Engineering for Data Analysis Python, Pandas, ChatGPT ChatGPT與Python&#xff1a;無需編程。借助ChatGPT、Python、Pandas及提示工程進行數據分析與數據可視化 "利用Python、Pandas和ChatGPT進行數據分析的提示工程"是一門開創性的課程&#xff0c;它通…