動態規劃:最長遞增子序列

給定一個數組,求最長遞增子序列的長度,就是要求我們求出一個序列中最長的上升子序列的長度,最長上升子序列的定義就是從原序列中按照孫旭去除一些數字,這些數字是逐漸增大的。

*定義dp[i]表示以第i個元素結尾的最長上升子序列的長度。

*初始時,每個dp[i]的值至少為1,因為每個元素本身就是一個長度為1的上升子序列

*對于每個元素i,我們遍歷起前面的所有元素j,如果nums[i] < nums[j],則更新

dp[i] = max(dp[i],dp[j] + 1)

*最終,最長上升子序列的長度就是dp數組中的最大值。

函數邏輯

  1. 輸入與邊界處理

    • 輸入為整數向量?nums

    • 若數組為空(n == 0),直接返回 0。

  2. 動態規劃初始化

    • 創建長度為?n?的數組?dp,初始值全為 1。dp[i]?表示以?nums[i]?結尾的最長遞增子序列的長度(每個元素自身至少構成長度為 1 的子序列)。

  3. 動態規劃遞推

    • 外層循環遍歷每個元素?nums[i](從第 2 個元素開始)。

    • 內層循環遍歷?nums[i]?之前的所有元素?nums[j]j < i)。

    • 若?nums[j] < nums[i],說明可以將?nums[i]?接在?nums[j]?對應的遞增子序列后。此時更新?dp[i]?為?max(dp[i], dp[j] + 1),確保?dp[i]?記錄當前最長長度。

  4. 返回結果

    • 最終返回?dp?數組中的最大值,即整個數組的最長遞增子序列長度。

示例驗證

以輸入?[10, 9, 2, 5, 3, 7, 101, 18]?為例:

  • dp?數組逐步更新為?[1, 1, 1, 2, 2, 3, 4, 4]

  • 最大值為 4,對應最長遞增子序列如?[2, 5, 7, 101]

復雜度分析

  • 時間復雜度:O(n2),兩層嵌套循環遍歷所有元素對。

  • 空間復雜度:O(n),用于存儲?dp?數組。

#include <iostream>
#include <vector>
#include <algorithm> // 用于max_elementusing namespace std;/*** 使用動態規劃求最長遞增子序列長度* @param nums 輸入數組* @return 最長遞增子序列的長度*/
int lengthOfLIS(vector<int>& nums) {int n = nums.size();if (n == 0) return 0;// dp[i]表示以nums[i]結尾的最長遞增子序列的長度vector<int> dp(n, 1); // 初始化為1,每個元素自身就是一個子序列for (int i = 1; i < n; ++i) {for (int j = 0; j < i; ++j) {if (nums[j] < nums[i]) {// 如果nums[j] < nums[i],則可以擴展子序列dp[i] = max(dp[i], dp[j] + 1);}}}// 返回dp數組中的最大值return *max_element(dp.begin(), dp.end());
}/*** 輸出最長遞增子序列本身(而不僅僅是長度)* @param nums 輸入數組* @return 最長遞增子序列*/
vector<int> getLIS(vector<int>& nums) {int n = nums.size();if (n == 0) return {};vector<int> dp(n, 1);vector<int> prev(n, -1); // 用于記錄前驅元素索引for (int i = 1; i < n; ++i) {for (int j = 0; j < i; ++j) {if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {dp[i] = dp[j] + 1;prev[i] = j; // 記錄前驅}}}// 找到dp數組中最大值的索引int max_len = 0, max_index = 0;for (int i = 0; i < n; ++i) {if (dp[i] > max_len) {max_len = dp[i];max_index = i;}}// 回溯構建LISvector<int> lis;while (max_index != -1) {lis.push_back(nums[max_index]);max_index = prev[max_index];}reverse(lis.begin(), lis.end()); // 反轉得到正確順序return lis;
}int main() {vector<int> nums = {10, 9, 2, 5, 3, 7, 101, 18};// 計算并輸出最長遞增子序列長度int length = lengthOfLIS(nums);cout << "最長遞增子序列長度: " << length << endl;// 獲取并輸出最長遞增子序列本身vector<int> lis = getLIS(nums);cout << "最長遞增子序列: ";for (int num : lis) {cout << num << " ";}cout << endl;return 0;
}

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

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

相關文章

湖北理元理律師事務所:債務優化如何實現還款與生活的平衡?

債務壓力往往讓債務人陷入“還款還是生存”的兩難選擇。湖北理元理律師事務所通過案例實踐發現&#xff0c;科學規劃的核心在于平衡法律義務與基本生活保障&#xff0c;而非單純追求債務縮減。本文結合實務經驗&#xff0c;解析債務優化的可行路徑。 剛性需求優先&#xff1a;…

重力場模型、球諧函數以及重力異常

地球重力場有兩種表達方法&#xff1a; 1、拉普拉斯&#xff08;Laplace&#xff09;方法&#xff0c;將重力場展開為球諧級數。 2、斯托克斯&#xff08;Stokes&#xff09;方法&#xff0c;根據地球的總質量和旋轉角速度計算。 本篇主要說第一種方法&#xff0c;該方法將地…

MySQL的視圖

一、MySQL視圖的介紹和作用 MySQL視圖&#xff0c;加油兄弟們&#xff0c;孰能生巧&#xff0c;完整代碼在最后&#xff01;&#xff01;&#xff01; 視圖是一個虛擬的表&#xff0c;并不是真是存在的&#xff0c;視圖其實并沒有真實的數據&#xff0c;他只是根據一個sql語句…

Scala與Go的異同教程

當瑞士軍刀遇到電鋸&#xff1a;Scala vs Go的相愛相殺之旅 各位準備禿頭的程序猿們&#xff08;放心&#xff0c;用Go和Scala不會加重你的發際線問題&#xff09;&#xff0c;今天我們來聊聊編程界的"冰與火之歌"——Scala和Go的異同。準備好瓜子飲料&#xff0c;我…

SaaS場快訂平臺項目說明【持續更新】

一、項目介紹 SaaS場快訂平臺是一個高效、便捷的體育場館在線預訂平臺。本項目采用SaaS方式開發&#xff0c;用戶不需要安裝軟件&#xff0c;直接通過互聯網訪問在線程序即可使用。本項目主要構建了一個體育館預訂系統&#xff0c;項目的功能主要包括&#xff1a;用戶注冊與登…

linux中常用的命令(三)

目錄 1- ls(查看當前目錄下的內容) 2- pwd (查看當前所在的文件夾) 3- cd [目錄名]&#xff08;切換文件夾&#xff09; 4- touch [文件名] &#xff08;如果文件不存在&#xff0c;新建文件&#xff09; 5- mkdir[目錄名] &#xff08;創建目錄&#xff09; 6-rm[文件名]&…

使用Simulink開發Autosar Nvm存儲邏輯

文章目錄 前言Autosar Nvm接口設計模型及接口生成代碼及arxmlRTE接口mappingRTE代碼分析總結 前言 之前介紹過Simulink開發Dem故障觸發邏輯&#xff0c;本文接著介紹另外一個常用的功能-Nvm存儲的實現。 Autosar Nvm接口 Autosar Nvm中一般在上電初始化的時調用Nvm_ReadAll獲…

Java—— 泛型詳解

泛型概述 泛型是JDK5中引入的特性&#xff0c;可以在編譯階段約束操作的數據類型&#xff0c;并進行檢查。 泛型的格式&#xff1a;<數據類型> 注意&#xff1a;泛型只能支持引用數據類型。 泛型的好處 沒有泛型的時候&#xff0c;可以往集合中添加任意類型的數據&#x…

通俗的橋接模式

橋接模式&#xff08;Bridge Pattern&#xff09; 就像一座橋&#xff0c;把兩個原本獨立變化的東西連接起來&#xff0c;讓它們可以各自自由變化&#xff0c;互不干擾。簡單來說&#xff0c;就是 “把抽象和實現分開&#xff0c;用組合代替繼承”。 一句話理解橋接模式 假設你…

【現代深度學習技術】注意力機制04:Bahdanau注意力

【作者主頁】Francek Chen 【專欄介紹】 ? ? ?PyTorch深度學習 ? ? ? 深度學習 (DL, Deep Learning) 特指基于深層神經網絡模型和方法的機器學習。它是在統計機器學習、人工神經網絡等算法模型基礎上&#xff0c;結合當代大數據和大算力的發展而發展出來的。深度學習最重…

爬蟲學習————開始

&#x1f33f;自動化的思想 任何領域的發展原因————“不斷追求生產方式的改革&#xff0c;即使得付出與耗費精力越來愈少&#xff0c;而收獲最大化”。由此&#xff0c;創造出方法和設備來提升效率。 如新聞的5W原則直接讓思考過程規范化、流程化。或者前端框架/后端輪子的…

每天五分鐘機器學習:KTT條件

本文重點 在前面的課程中,我們學習了拉格朗日乘數法求解等式約束下函數極值,如果約束不是等式而是不等式呢?此時就需要KTT條件出手了,KTT條件是拉格朗日乘數法的推廣。KTT條件不僅統一了等式約束與不等式約束的優化問題求解范式,KTT條件給出了這類問題取得極值的一階必要…

leetcode0829. 連續整數求和-hard

1 題目&#xff1a; 連續整數求和 官方標定難度&#xff1a;難 給定一個正整數 n&#xff0c;返回 連續正整數滿足所有數字之和為 n 的組數 。 示例 1: 輸入: n 5 輸出: 2 解釋: 5 2 3&#xff0c;共有兩組連續整數([5],[2,3])求和后為 5。 示例 2: 輸入: n 9 輸出: …

window 顯示驅動開發-線性伸縮空間段

線性伸縮空間段類似于線性內存空間段。 但是&#xff0c;伸縮空間段只是地址空間&#xff0c;不能容納位。 若要保存位&#xff0c;必須分配系統內存頁&#xff0c;并且必須重定向地址空間范圍以引用這些頁面。 內核模式顯示微型端口驅動程序&#xff08;KMD&#xff09;必須實…

Cadence 高速系統設計流程及工具使用三

5.8 約束規則的應用 5.8.1 層次化約束關系 在應用約束規則之前&#xff0c;我們首先要了解這些約束規則是如何作用在 Cadence 設計對象上的。Cadence 中對設計對象的劃分和概念&#xff0c;如表 5-11 所示。 在 Cadence 系統中&#xff0c;把設計對象按層次進行了劃分&#…

ScaleTransition 是 Flutter 中的一個動畫組件,用于實現縮放動畫效果。

ScaleTransition 是 Flutter 中的一個動畫組件&#xff0c;用于實現縮放動畫效果。它允許你對子組件進行動態的縮放變換&#xff0c;從而實現平滑的動畫效果。ScaleTransition 通常與 AnimationController 和 Tween 一起使用&#xff0c;以控制動畫的開始、結束和過渡效果。 基…

深入解析:如何基于開源p-net快速開發Profinet從站服務

一、Profinet協議與軟協議棧技術解析 1.1 工業通信的"高速公路" Profinet作為工業以太網協議三巨頭之一,采用IEEE 802.3標準實現實時通信,具有: 實時分級:支持RT(實時)和IRT(等時實時)通信模式拓撲靈活:支持星型、樹型、環型等多種網絡結構對象模型:基于…

m個n維向量組中m,n的含義與空間的關系

向量的維度與空間的關系&#xff1a; 一個向量的維度由其分量個數決定&#xff0c;例如 ( n ) 個分量的向量屬于 Rn空間 。 向量組張成空間的維度&#xff1a; 當向量組有 ( m ) 個線性無關的 ( n ) 維向量時&#xff1a; 若 ( m < n )&#xff1a; 這些向量張成的是 Rn中的…

excel大表導入數據庫

前文介紹了數據量較小的excel表導入數據庫的方法&#xff0c;在數據量較大的情況下就不太適合了&#xff0c;一個是因為mysql命令的執行串長度有限制&#xff0c;二是node-xlsx這個模塊加載excel文件是整個文件全部加載到內存&#xff0c;在excel文件較大和可用內存受限的場景就…

Python 爬蟲基礎入門教程(超詳細)

一、什么是爬蟲&#xff1f; 網絡爬蟲&#xff08;Web Crawler&#xff09;&#xff0c;又稱網頁蜘蛛&#xff0c;是一種自動抓取互聯網信息的程序。爬蟲會模擬人的瀏覽行為&#xff0c;向網站發送請求&#xff0c;然后獲取網頁內容并提取有用的數據。 二、Python爬蟲的基本原…