Day43--動態規劃--674. 最長連續遞增序列,300. 最長遞增子序列,718. 最長重復子數組

Day43–動態規劃–674. 最長連續遞增序列,300. 最長遞增子序列,718. 最長重復子數組

674. 最長連續遞增序列

方法:動態規劃

思路:

  1. dp[i]含義:到i這個位置(包含i)的連續遞增子序列的長度
  2. 遞推公式:if (nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1;
  3. 初始化:每一個nums[i]的子序列都至少是1,就是自己。Arrays.fill(dp, 1); int maxLen = 1;
  4. 遍歷方向:正序
// 動態規劃
class Solution {public int findLengthOfLCIS(int[] nums) {int n = nums.length;// dp[i]含義:到i這個位置(包含i)的連續遞增子序列的長度int[] dp = new int[n];// 初始化:每一個nums[i]的子序列都至少是1,就是自己Arrays.fill(dp, 1);int maxLen = 1;// 從1開始遍歷for (int i = 1; i < n; i++) {if (nums[i] > nums[i - 1]) {dp[i] = dp[i - 1] + 1;// 刷新最大值maxLen = Math.max(maxLen, dp[i]);}}return maxLen;}
}

方法:貪心

思路:

連續遞增,就不斷len++;不連續了,就更新最大值。

如果最長串,剛好到末尾的話,出了循環還要更新一次最大值。

class Solution {public int findLengthOfLCIS(int[] nums) {int n = nums.length;// 題目說n>1。所以至少有一個nums[i]。每個nums[i]的長度都是1int len = 1;int maxLen = 1;// 從1開始遍歷(如果n==1的話,不進這個循環,答案也是對的)for (int i = 1; i < n; i++) {if (nums[i] > nums[i - 1]) {// 連續遞增len++;} else {// 不連續了。刷新最大值maxLen = Math.max(maxLen, len);// 每個nums[i]的長度都是1len = 1;}}// 如果最長串,剛好到末尾的話。maxLen還沒取到,所以出了循環還要再取一次return Math.max(maxLen, len);}
}

思路:

另一種寫法

class Solution {public int findLengthOfLCIS(int[] nums) {int n = nums.length;// 題目說n>1。所以至少有一個nums[i]。每個nums[i]的長度都是1int len = 1;int maxLen = 1;// 從1開始遍歷(如果n==1的話,不進這個循環,答案也是對的)for (int i = 1; i < n; i++) {if (nums[i] > nums[i - 1]) {// 連續遞增len++;} else {// 重新開始,每個nums[i]的長度都是1len = 1;}// 如果有更大值,刷新maxLenif (len > maxLen) {maxLen = len;}}return maxLen;}
}

300. 最長遞增子序列

方法:動態規劃

思路:

  1. dp含義:dp[i]表示i之前包括i的以nums[i]結尾的最長遞增子序列的長度
  2. 遞歸公式:
    • 本意就是取出最大的dp[j]+1。通俗點來講,就是接在哪個j后面,能有最大長度。
    • if (nums[i] > nums[j]) dp[i] = Math.max(dp[i], dp[j] + 1);
  3. 初始化:每一個nums[i]的子序列都至少是1,就是自己Arrays.fill(dp, 1);
  4. 遍歷方向:正序
// 動態規劃
class Solution {public int lengthOfLIS(int[] nums) {int n = nums.length;// dp含義:dp[i]表示i之前包括i的以nums[i]結尾的最長遞增子序列的長度int[] dp = new int[n];// 題目說n>=1,所以res至少也有1int res = 1;// 初始化:每一個nums[i]的子序列都至少是1,就是自己Arrays.fill(dp, 1);// 從1開始遍歷for (int i = 1; i < n; i++) {// 從[0-i]中找,所以復雜度是O(n^2)for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {// 注意這里的max函數,本意不是為了比較dp[i]和dp[j]+1,而是為了取出本層最大的dp[i],因為j在遍歷嘛// 本意就是取出最大的dp[j]+1。通俗點來講,就是接在哪個j后面,能有最大長度dp[i] = Math.max(dp[i], dp[j] + 1);}}// 更新resres = Math.max(res, dp[i]);}return res;}
}

方法:貪心+二分

思路來自力扣官方題解

思路:

  • 考慮一個簡單的貪心,如果我們要使上升子序列盡可能的長,則我們需要讓序列上升得盡可能慢,因此我們希望每次在上升子序列最后加上的那個數盡可能的小。

  • 基于上面的貪心思路,我們維護一個數組 d[i] ,表示長度為 i 的最長上升子序列的末尾元素,用 len 記錄目前最長上升子序列的長度,起始時 len 為 1,d[1]=nums[0]。

  • 設當前已求出的最長上升子序列的長度為 len(初始時為 1),從前往后遍歷數組 nums,在遍歷到 nums[i] 時:

    • 如果 nums[i]>d[len] ,則直接加入到 d 數組末尾,并更新 len=len+1;
    • 否則,在 d 數組中二分查找,找到第一個比 nums[i] 小的數 d[k] ,并更新 d[k+1]=nums[i]。
// 貪心 + 二分(時間復雜度nlogn)
class Solution {public int lengthOfLIS(int[] nums) {int n = nums.length;if (n == 0) {return 0;}int len = 1;int[] d = new int[n + 1];d[len] = nums[0];for (int i = 1; i < n; i++) {if (nums[i] > d[len]) {d[++len] = nums[i];} else {// 調用二分查找函數尋找合適的位置int pos = binarySearch(d, 1, len, nums[i]);d[pos + 1] = nums[i];}}return len;}// 二分查找函數,單獨提取出來private int binarySearch(int[] d, int left, int right, int target) {int pos = 0; // 如果找不到說明所有的數都比 target 大,此時要更新 d[1],所以這里將 pos 設為 0while (left <= right) {int mid = left - ((left - right) >> 1);if (d[mid] < target) {pos = mid;left = mid + 1;} else {right = mid - 1;}}return pos;}
}

718. 最長重復子數組

注意,這題雖然說是“子數組”,但是實際上是按“子序列”理解。

子數組是可以重新排序的,子序列是不能改變原有的順序的(但是可以跳過一些元素)

方法:暴力

思路:

每當nums1[i] == nums2[j]的時候,記錄while(nums1[ii++] == nums2[jj++])的長度。

但是這個方法的時間復雜度很恐怖,去到O(n^3)

class Solution {public int findLength(int[] nums1, int[] nums2) {int maxLen = 0;int n1 = nums1.length;int n2 = nums2.length;for (int i = 0; i < n1; i++) {for (int j = 0; j < n2; j++) {if (nums1[i] == nums2[j]) {int ii = i;int jj = j;while (ii < n1 && jj < n2 && nums1[ii] == nums2[jj]) {ii++;jj++;}int len = ii - i;if (len > maxLen) {maxLen = len;}}}}return maxLen;}
}

方法:動態規劃(二維DP數組)

思路:

  1. dp[i][j]含義:以下標i - 1為結尾的A,和以下標j - 1為結尾的B,的最長重復子數組長度
  2. 遞推公式:
    • 前面的一位是相等的,那么dp[i][j]要等于dp[i - 1][j - 1] + 1,表明以下標i - 1為結尾的A,和以下標j - 1為結尾的B,最長重復子數組的長度增加了1
    • if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
  3. 初始化:0
  4. 遍歷順序:正序
// 動態規劃(二維DP數組)
class Solution {public int findLength(int[] nums1, int[] nums2) {int n1 = nums1.length;int n2 = nums2.length;// dp[i][j]含義:以下標i - 1為結尾的A,和以下標j - 1為結尾的B,的最長重復子數組長度int[][] dp = new int[n1 + 1][n2 + 1];int maxLen = 0;// 要從索引1開始遍歷,到索引n才結束for (int i = 1; i <= n1; i++) {for (int j = 1; j <= n2; j++) {// 前面的一位是相等的,那么dp[i][j]等于前面的長度+1。(告訴后面到我這有多長重復)if (nums1[i - 1] == nums2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;}// 刷新maxLenif (dp[i][j] > maxLen) {maxLen = dp[i][j];}}}return maxLen;}
}

方法:動態規劃(一維DP數組)

思路:

《代碼隨想錄》:

我們可以看出dp[i][j]都是由dp[i - 1][j - 1]推出。那么壓縮為一維數組,也就是dp[j]都是由dp[j - 1]推出。

也就是相當于可以把上一層dp[i - 1][j]拷貝到下一層dp[i][j]來繼續用。

此時遍歷B數組的時候,就要從后向前遍歷,這樣避免重復覆蓋

// 動態規劃(一維DP數組)
class Solution {public int findLength(int[] nums1, int[] nums2) {int n1 = nums1.length;int n2 = nums2.length;// 因為把nums1的維度壓縮了。所以要靠nums2作為dp// 所以要遍歷nums1,nums2每層的狀態要復用int[] dp = new int[n2 + 1];int maxLen = 0;for (int i = 1; i <= n1; i++) {// 因為要用到上一層的狀態,所以要倒序遍歷for (int j = n2; j > 0; j--) {if (nums1[i - 1] == nums2[j - 1]) {dp[j] = dp[j - 1] + 1;} else {dp[j] = 0; // 注意,不相等的話,要刷回0}// 刷新maxLenif (dp[j] > maxLen) {maxLen = dp[j];}}}return maxLen;}
}

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

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

相關文章

支持 UMD 自定義組件與版本控制:從 Schema 到動態渲染

源碼 ? 支持 UMD 自定義組件與版本控制&#xff1a;從 Schema 到動態渲染 在低代碼平臺或可視化大屏 SDK 中&#xff0c;支持用戶上傳自定義組件 是一個必備能力。 而在 React 場景下&#xff0c;自定義組件通常以 UMD 格式 打包并暴露為全局變量。 本篇文章&#xff0c;我…

zookeeper3.8.4安裝以及客戶端C++api編譯

服務端直接下載編譯好的bin版本 Apache Download Mirrors C客戶端需要編譯庫文件 zookeeper 3.8.4 使用與C API編譯 - 丘貍尾 - 博客園 雜七雜八的依賴 sudo apt update sudo apt install -y \autoconf automake libtool libtool-bin m4 pkg-config gettext \cmake build-es…

使用行為樹控制機器人(一) —— 節點

文章目錄一、背景需求二、創建ActionNodes1. 功能實現1.1 頭文件定義1.2 源文件實現1.3 main文件實現1.4 my_tree.xml 實現2. 執行結果三、 執行失敗處理1. 添加嘗試次數1.1 功能實現1.2 實驗結果2. 完善異常處理2.1 多節點組合兜底2.2 實驗結果使用行為樹控制機器人(一) —— …

JavaScript Window Location

JavaScript Window Location JavaScript中的window.location對象是操作瀏覽器地址欄URL的一個非常有用的對象。它允許開發者獲取當前頁面的URL、查詢字符串、路徑等&#xff0c;并且可以修改它們來導航到不同的頁面。以下是關于window.location的詳細解析。 1. window.location…

Kubernetes生產環境健康檢查自動化指南

核心腳本功能&#xff1a; 一鍵檢查集群核心組件狀態自動化掃描節點/Pod異常存儲與網絡關鍵指標檢測風險分級輸出&#xff08;紅/黃/綠標識&#xff09;一、自動化巡檢腳本 (k8s-health-check.sh) #!/bin/bash # Desc: Kubernetes全維度健康檢查腳本 # 執行要求&#xff1a;kub…

消息隊列系統測試報告

目錄 一、項目背景 二、RabbitMQ介紹 1.什么是RabbitMQ&#xff1f; 2.RabbitMQ的工作流程是怎么樣的&#xff1f; 3.項目設計 三、測試概述 MQ 測試目標&#xff1a; 測試用例統計&#xff1a; 核心模塊測試詳情及代碼示例&#xff1a; 1. 數據庫管理&#xff08;Da…

基于 Axios 的 HTTP 請求封裝文件解析

import axios from "axios"; import { ElMessage } from "element-plus"; import store from "/store"; import router from "/router";// 創建axios實例 const service axios.create({baseURL: "http://localhost:8080/api&quo…

PowerDesigner生成帶注釋的sql方法

前提是name里面是有文字的&#xff1a; 方法開始&#xff1a; 第一步&#xff1a; Database → Edit Current DBMS → Script → Objects → Column → Add 把輸出模板改成&#xff1a; %20:COLUMN% %30:DATATYPE%[.Z:[%Compressed%? compressed][ %NULLNOTNULL%][%IDENTITY…

獵板PCB:專業鍵盤PCB板解決方案供應商

獵板PCB深耕印刷電路板&#xff08;PCB&#xff09;制造領域&#xff0c;憑借前沿技術與深厚積淀&#xff0c;在鍵盤PCB板細分市場積極布局&#xff0c;致力于為不同客戶提供多樣化、高性能的鍵盤PCB板產品&#xff0c;滿足多元需求。一、定義&#xff1a;鍵盤PCB板鍵盤PCB板&a…

基于 Spring Boot 的登錄功能實現詳解

在 Web 應用開發中&#xff0c;登錄功能是保障系統安全的第一道防線。本文將結合實際代碼&#xff0c;詳細解析一個基于 Spring Boot 框架的登錄功能實現&#xff0c;包括驗證碼生成、用戶驗證、Token 機制等關鍵環節。技術棧概覽本登錄功能實現涉及以下核心技術和組件&#xf…

vue+django 大模型心理學智能診斷評測系統干預治療輔助系統、智慧心理醫療、帶知識圖譜

vuedjango 大模型心理學智能診斷評測系統干預治療輔助系統、智慧心理醫療、帶知識圖譜文章結尾部分有CSDN官方提供的學長 聯系方式名片 文章結尾部分有CSDN官方提供的學長 聯系方式名片 關注B站&#xff0c;有好處&#xff01;編號:D003 pro基于大模型心理學問卷、智能診斷&…

【linux】企業級WEB應用服務器tomcat

一 WEB技術1.1 HTTP協議和B/S 結構操作系統有進程子系統&#xff0c;使用多進程就可以充分利用硬件資源。進程中可以多個線程&#xff0c;每一個線程可以被CPU調度執行&#xff0c;這樣就可以讓程序并行的執行。這樣一臺主機就可以作為一個服務器為多個客戶端提供計算服務。客戶…

【Unity優化】Unity多場景加載優化與資源釋放完整指南:解決Additive加載卡頓、預熱、卸載與內存釋放問題

【Unity優化】Unity多場景加載優化與資源釋放完整指南&#xff1a;解決Additive加載卡頓、預熱、卸載與內存釋放問題 本文將完整梳理 Unity 中通過 SceneManager.LoadSceneAsync 使用 Additive 模式加載子場景時出現的卡頓問題&#xff0c;分析其本質&#xff0c;提出不同階段的…

B 樹與 B + 樹解析與實現

一、磁盤存儲優化的核心邏輯 在大規模數據處理場景中&#xff0c;磁盤 I/O 效率是性能瓶頸的核心。磁盤訪問具有以下特性&#xff1a; 隨機訪問成本高&#xff1a;磁頭尋道時間&#xff08;Seek Time&#xff09;可達毫秒級&#xff0c;相比內存訪問&#xff08;納秒級&#…

MySQL 查詢相同記錄并保留時間最晚的一條

要在 MySQL 中查詢相同記錄并僅保留時間最晚的那一條&#xff0c;你可以使用以下幾種方法&#xff1a;方法一&#xff1a;使用子查詢和 GROUP BY假設你的表名為 your_table&#xff0c;時間字段為 create_time&#xff0c;其他用于判斷記錄相同的字段為 field1, field2 等&…

在 .NET Core 5.0 中啟用 Gzip 壓縮 Response

在 .NET Core 5.0 中啟用 Gzip 壓縮 Response 在 .NET Core 5.0 (ASP.NET Core 5.0) 中啟用 Gzip 壓縮主要通過響應壓縮中間件實現。以下是詳細配置步驟&#xff1a; 1. 安裝必要的 NuGet 包 首先確保已安裝響應壓縮包&#xff1a; dotnet add package Microsoft.AspNetCore.Re…

[Oracle] TRUNC()函數

TRUNC() 是 Oracle 中一個多功能函數&#xff0c;主要用于對數值、日期進行截斷操作1.TRUNC()函數用于數值處理語法格式TRUNC(number, decimal_places)參數說明number&#xff1a;要截斷的數值 decimal_places&#xff1a;保留的小數位數(可選)&#xff0c;默認為0(截斷所有小數…

GPT-oss:OpenAI再次開源新模型,技術報告解讀

1.簡介OpenAI 發布了兩款開源權重推理模型 gpt-oss-120b 與 gpt-oss-20b&#xff0c;均采用 Apache 2.0 許可&#xff0c;主打在代理工作流中執行復雜推理、調用工具&#xff08;如搜索、Python 代碼執行&#xff09;并嚴格遵循指令。120b 為 36 層 MoE 結構&#xff0c;活躍參…

python tcp 框架

目錄 python tcp 框架 asyncio websockets python tcp 框架 asyncio import asyncio import json import timeclass TCPClient:def __init__(self, host, port, heartbeat_interval10):self.host hostself.port portself.heartbeat_interval heartbeat_intervalself.read…