動態規劃求解leetcode300.最長遞增子序列(LIS)詳解

給你一個整數數組?nums?,找到其中最長嚴格遞增子序列的長度。

子序列?是由數組派生而來的序列,刪除(或不刪除)數組中的元素而不改變其余元素的順序。例如,[3,6,2,7]?是數組?[0,3,1,6,2,2,7]?的子序列。

示例 1:

輸入:nums = [10,9,2,5,3,7,101,18]
輸出:4
解釋:最長遞增子序列是 [2,3,7,101],因此長度為 4 。

示例 2:

輸入:nums = [0,1,0,3,2,3]
輸出:4

示例 3:

輸入:nums = [7,7,7,7,7,7,7]
輸出:1

關鍵點

  • 雙重循環結構:外層循環遍歷每個元素作為子序列結尾,內層循環檢查所有可能的前驅元素

  • 遞增條件:只有當?nums[j] < nums[i]?時才考慮狀態轉移

  • 時間復雜度:O(n2),因為有兩層嵌套循環

核心思路

  1. 定義狀態

    • dp[i]?表示以?nums[i]?結尾的最長遞增子序列的長度

    • 初始時每個元素本身就是一個長度為1的子序列,所以初始化?dp?數組全為1

  2. 狀態轉移

    • 對于每個?i(當前元素),檢查所有?j < i(前面的元素)

    • 如果?nums[j] < nums[i](滿足遞增條件),則嘗試更新?dp[i]

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

      這表示如果接在?nums[j]?后面能形成更長的子序列,就更新?dp[i]

  3. 記錄結果

    • 在計算過程中持續維護一個全局最大值?res

    • 最終?res?就是整個數組的最長遞增子序列長度

// Dynamic programming.
class Solution {public int lengthOfLIS(int[] nums) {if(nums.length == 0) return 0;int[] dp = new int[nums.length];int res = 0;Arrays.fill(dp, 1);for(int i = 0; i < nums.length; i++) {for(int j = 0; j < i; j++) {if(nums[j] < nums[i]) dp[i] = Math.max(dp[i], dp[j] + 1);}res = Math.max(res, dp[i]);}return res;}
}

示例數組

nums = [10, 9, 2, 5, 3, 7, 101, 18]

算法步驟解析

  1. 初始化

    • 創建dp數組,長度與nums相同,初始值全為1(因為每個元素本身就是一個長度為1的子序列)

    dp = [1, 1, 1, 1, 1, 1, 1, 1]
  2. 雙重循環處理

    • 外層循環:i從0到n-1

    • 內層循環:j從0到i-1

  3. 逐步計算過程

    i=0?(nums[0]=10):

    • j無(因為i=0時j從0到-1)

    • dp保持不變:[1, 1, 1, 1, 1, 1, 1, 1]

    • res=1

    i=1?(nums[1]=9):

    • j=0: nums[0]=10 > nums[1]=9 → 不更新

    • dp保持不變:[1, 1, 1, 1, 1, 1, 1, 1]

    • res=1

    i=2?(nums[2]=2):

    • j=0: nums[0]=10 > nums[2]=2 → 不更新

    • j=1: nums[1]=9 > nums[2]=2 → 不更新

    • dp保持不變:[1, 1, 1, 1, 1, 1, 1, 1]

    • res=1

    i=3?(nums[3]=5):

    • j=0: nums[0]=10 > nums[3]=5 → 不更新

    • j=1: nums[1]=9 > nums[3]=5 → 不更新

    • j=2: nums[2]=2 < nums[3]=5 → dp[3] = max(dp[3], dp[2]+1) = max(1, 2) = 2

    • dp更新為:[1, 1, 1, 2, 1, 1, 1, 1]

    • res=2

    i=4?(nums[4]=3):

    • j=0: nums[0]=10 > nums[4]=3 → 不更新

    • j=1: nums[1]=9 > nums[4]=3 → 不更新

    • j=2: nums[2]=2 < nums[4]=3 → dp[4] = max(dp[4], dp[2]+1) = max(1, 2) = 2

    • j=3: nums[3]=5 > nums[4]=3 → 不更新

    • dp更新為:[1, 1, 1, 2, 2, 1, 1, 1]

    • res=2

    i=5?(nums[5]=7):

    • j=0: nums[0]=10 > nums[5]=7 → 不更新

    • j=1: nums[1]=9 > nums[5]=7 → 不更新

    • j=2: nums[2]=2 < nums[5]=7 → dp[5] = max(dp[5], dp[2]+1) = max(1, 2) = 2

    • j=3: nums[3]=5 < nums[5]=7 → dp[5] = max(dp[5], dp[3]+1) = max(2, 3) = 3

    • j=4: nums[4]=3 < nums[5]=7 → dp[5] = max(dp[5], dp[4]+1) = max(3, 3) = 3

    • dp更新為:[1, 1, 1, 2, 2, 3, 1, 1]

    • res=3

    i=6?(nums[6]=101):

    • j=0: nums[0]=10 < nums[6]=101 → dp[6] = max(dp[6], dp[0]+1) = max(1, 2) = 2

    • j=1: nums[1]=9 < nums[6]=101 → dp[6] = max(dp[6], dp[1]+1) = max(2, 2) = 2

    • j=2: nums[2]=2 < nums[6]=101 → dp[6] = max(dp[6], dp[2]+1) = max(2, 2) = 2

    • j=3: nums[3]=5 < nums[6]=101 → dp[6] = max(dp[6], dp[3]+1) = max(2, 3) = 3

    • j=4: nums[4]=3 < nums[6]=101 → dp[6] = max(dp[6], dp[4]+1) = max(3, 3) = 3

    • j=5: nums[5]=7 < nums[6]=101 → dp[6] = max(dp[6], dp[5]+1) = max(3, 4) = 4

    • dp更新為:[1, 1, 1, 2, 2, 3, 4, 1]

    • res=4

    i=7?(nums[7]=18):

    • j=0: nums[0]=10 < nums[7]=18 → dp[7] = max(dp[7], dp[0]+1) = max(1, 2) = 2

    • j=1: nums[1]=9 < nums[7]=18 → dp[7] = max(dp[7], dp[1]+1) = max(2, 2) = 2

    • j=2: nums[2]=2 < nums[7]=18 → dp[7] = max(dp[7], dp[2]+1) = max(2, 2) = 2

    • j=3: nums[3]=5 < nums[7]=18 → dp[7] = max(dp[7], dp[3]+1) = max(2, 3) = 3

    • j=4: nums[4]=3 < nums[7]=18 → dp[7] = max(dp[7], dp[4]+1) = max(3, 3) = 3

    • j=5: nums[5]=7 < nums[7]=18 → dp[7] = max(dp[7], dp[5]+1) = max(3, 4) = 4

    • j=6: nums[6]=101 > nums[7]=18 → 不更新

    • dp更新為:[1, 1, 1, 2, 2, 3, 4, 4]

    • res=4

最終結果

最長遞增子序列的長度為4。對應的子序列可以是:

  • [2, 3, 7, 101]

  • 或 [2, 5, 7, 101]

  • 或 [2, 3, 7, 18]

  • 或 [2, 5, 7, 18]

?

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

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

相關文章

Rule.resourceQuery(通過路徑參數指定loader匹配規則)

1. 說明 在 webpack 4 中&#xff0c;Rule.resourceQuery 是一個用于根據文件路徑中的 查詢參數&#xff08;query string&#xff09; 來匹配資源的配置項。它允許你針對帶有特定查詢條件的文件&#xff08;如 file.css?inline 或 image.png?raw&#xff09;應用不同的加載…

快速上手 MetaGPT

1. MetaGPT 簡介 在當下的大模型應用開發領域&#xff0c;Agent 無疑是最炙手可熱的方向&#xff0c;這也直接催生出了眾多的 Agent 開發框架。在這之中&#xff0c; MetaGPT 是成熟度最高、使用最廣泛的開發框架之一。 MetaGPT 是一款備受矚目的多智能體開發框架&#xff0c…

新聞數據接口開發指南:從多源聚合到NLP摘要生成

隨著人工智能&#xff08;AI&#xff09;技術的飛速發展&#xff0c;新聞行業也迎來了新的變革。AI不僅能夠自動化生成新聞內容&#xff0c;還能通過智能推薦系統為用戶提供個性化的新聞體驗。萬維易源提供的“新聞查詢”API接口&#xff0c;結合了最新的AI技術&#xff0c;為開…

每天五分鐘深度學習框架pytorch:使用visdom繪制損失函數圖像

visdom的安裝 pip install visdom如果安裝失敗 pip install --upgrade visdom開啟visdom python -m visdom.server nohup python -m visdom.server后臺啟動然后就會出現,下面的頁面,我們可以使用下面的鏈接打開visdom頁面 Visdom中有兩個重要概念: env環境。不同環境的可…

UnityEditor - 調用編輯器菜單功能

例如: 調用Edit/Frame Selected In Scene EditorApplication.ExecuteMenuItem("Edit/Frame Selected in Scene"); EditorApplication.ExecuteMenuItem("Edit/Lock view to Selected");

電化學-論文分享-NanoStat: An open source, fully wireless potentiostat

電化學-論文分享-NanoStat: An open source, fully wireless potentiostat 發現了一篇近期有關便攜式電化學工作站相關方面的論文&#xff08;2022&#xff09;&#xff0c;并且全部工作內容都是開源的&#xff0c;硬件電路圖、PCB板、嵌入式代碼以及網頁代碼、設備外殼所有資…

ZYNQ----------PS端入門(四)(根文件系統進emmc,鏡像和設備樹進flash)

文章目錄 系列文章目錄前言一、根文件系統是什么&#xff1f;二、根文件系統燒進emmc1.emmc是什么&#xff1f;2.根文件系統的位置3.分離根文件系統步驟1.14.分離根文件系統步驟1.25.分離根文件系統步驟2.1 三、根文件系統進emmc&#xff0c;設備樹和鏡像進flash 系列文章目錄 …

uniapp+vue3移動端實現輸入驗證碼

ios安卓 uniappvue3 微信小程序端 <template><view class"verification-code"><view class"verification-code__display"><block v-for"i in numberArr" :key"i"><view:class"[verification-code__d…

如何選擇游戲支付平臺呢?

如果要選擇一個游戲支付平臺的話&#xff0c;那么你可以考慮一下這個平臺&#xff1a;功能非常多&#xff0c;支付模式很高效&#xff0c;功能很全&#xff0c;服務很貼心&#xff0c;資金安全靠得住&#xff0c;安全認證模式也很可靠。 第二&#xff0c;結算方法也很多&#x…

前端如何獲取文件的 Hash 值?多種方式詳解、對比與實踐指南

文章目錄 前言一、Hash 值為何重要&#xff1f;二、Hash 值基礎知識2.1 什么是 Hash&#xff1f;2.2 Hash 在前端的應用場景2.3 常見的 Hash 算法&#xff08;MD5、SHA 系列&#xff09; 三、前端獲取文件 Hash 的常用方式3.1 使用 SparkMD5 計算 MD5 值3.2 使用 Web Crypto AP…

【Java學習筆記】類與對象

類與對象 什么是類&#xff1f; 知識遷移&#xff1a;類比 C 語言中的結構體 類的描述 類是一個對象的抽象&#xff0c;從字面意思就表示一個類的事物&#xff0c;類具有屬性和方法&#xff08;行為&#xff09;&#xff0c;對象是類的一個具體表現 總結&#xff1a;類是對象…

如何對極狐GitLab 議題進行過濾和排序?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 排序和議題列表排序 (BASIC ALL) 您可以通過多種方式對議題列表進行排序&#xff0c;可用的排序選項可以根據列表的上下文進…

k8s中資源的介紹及標準資源namespaces實踐

文章目錄 第1章 k8s中的資源(resources)介紹1.1 k8s中資源(resouces)的分類1.2 k8s中資源(resources)的級別1.3 k8s中資源(resources)的API規范1.4 k8s中資源(resources)的manifests 第2章 k8s中的標準資源之namespaces的實踐2.1 基本介紹2.2 編寫相關ns資源對象的manifests2.3…

優化uniappx頁面性能,處理頁面滑動卡頓問題

問題&#xff1a;在頁面遇到滑動特別卡的情況就是在頁面使用了動態樣式或者動態類&#xff0c;做切換的時候頁面重新渲染導致頁面滑動卡頓 解決&#xff1a;把動態樣式和動態類做的樣式切換改為通過獲取元素修改樣式屬性值 循環修改樣式示例 bannerList.forEach((_, index)…

DeepSeek賦能Nuclei:打造網絡安全檢測的“超級助手”

引言 各位少俠&#xff0c;周末快樂&#xff0c;幸會幸會&#xff01; 今天嘮一個超酷的技術組合——用AI大模型給Nuclei開掛&#xff0c;提升漏洞檢測能力&#xff01; 想象一下&#xff0c;當出現新漏洞時&#xff0c;少俠們經常需要根據Nuclei模板&#xff0c;手動扒漏洞文章…

leetcode - 字符串

字符串 466. 統計重復個數 題目 定義 str [s, n] 表示 str 由 n 個字符串 s 連接構成。 例如&#xff0c;str ["abc", 3] "abcabcabc" 。 如果可以從 s2( )中刪除某些字符使其變為 s1&#xff0c;則稱字符串 s1( )可以從字符串 s2 獲得。 例如&#xf…

Java求職者面試:從Spring Boot到微服務的技術深度探索

場景&#xff1a;互聯網大廠Java求職者面試 角色介紹&#xff1a; 面試官&#xff1a;技術精湛&#xff0c;負責把控面試質量。謝飛機&#xff1a;搞笑的程序員&#xff0c;偶爾能答對問題。 第一輪&#xff1a;基礎知識 面試官&#xff1a;謝飛機&#xff0c;你能簡要介紹…

榕壹云國際版短劇系統:基于Spring Boot+MySQL+UniApp的全球短劇創作平臺

一、項目背景與簡介 在短視頻行業高速發展的今天&#xff0c;短劇內容已成為全球用戶娛樂消費的新寵。為滿足市場對高質量、多樣化短劇的需求&#xff0c;我們基于Spring Boot MySQL UniApp技術棧開發了榕壹云國際版短劇系統&#xff0c;這是一款面向全球市場的短劇創作與分…

資料分享!瑞芯微RK3506(3核ARM+Cortex-A7 + ARM Cortex-M0)工業評估板硬件資料

前 言 本文主要介紹TL3506-EVM評估板硬件接口資源以及設計注意事項等內容。 RK3506J/RK3506B處理器的IO電平標準一般為1.8V、3.3V,上拉電源一般不超過3.3V或1.8V,當外接信號電平與IO電平不匹配時,中間需增加電平轉換芯片或信號隔離芯片。按鍵或接口需考慮ESD設計,ESD器…

C#通過NTP服務器獲取NTP時間

C#通過NTP服務器獲取NTP時間 注意事項&#xff1a; 如果NTP服務器地址是域名&#xff0c;如阿里云的NTP服務器地址。需要DNS解析。NTP使用UDP通訊&#xff0c;默認端口是123NTP經過很多年的發展&#xff0c;有4個版本號&#xff0c;目前常用的3和4。NTP區分客戶端和服務端&am…