欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于最長(zhǎng)遞增子序列問(wèn)題概述

 更新時(shí)間:2025年02月14日 15:18:31   作者:阿賈克斯的黎明  
本文詳細(xì)介紹了最長(zhǎng)遞增子序列問(wèn)題的定義及兩種優(yōu)化解法:貪心+二分查找和動(dòng)態(tài)規(guī)劃+狀態(tài)壓縮,貪心+二分查找時(shí)間復(fù)雜度為O(nlogn),通過(guò)維護(hù)一個(gè)有序的“尾巴”數(shù)組來(lái)高效地找到最長(zhǎng)遞增子序列,動(dòng)態(tài)規(guī)劃+狀態(tài)壓縮則通過(guò)狀態(tài)壓縮將空間復(fù)雜度優(yōu)化至O(n)

一、最長(zhǎng)遞增子序列問(wèn)題概述

1. 問(wèn)題定義

給定一個(gè)整數(shù)序列,例如 nums = [10, 9, 2, 5, 3, 7, 101, 18],要找出它的一個(gè)最長(zhǎng)的子序列,使得這個(gè)子序列中的元素是嚴(yán)格遞增的。

在上述例子中,最長(zhǎng)遞增子序列是 [2, 3, 7, 101] 或者 [2, 5, 7, 101] 等,長(zhǎng)度為 4。

2. 常規(guī)動(dòng)態(tài)規(guī)劃解法思路及缺點(diǎn)

思路

  • 通常可以定義一個(gè) dp 數(shù)組,其中 dp[i] 表示以 nums[i] 為結(jié)尾的最長(zhǎng)遞增子序列的長(zhǎng)度。
  • 狀態(tài)轉(zhuǎn)移方程一般為 dp[i] = max(dp[j]) + 1(其中 0 <= j < inums[j] < nums[i]),也就是遍歷前面所有小于 nums[i] 的元素對(duì)應(yīng)的 dp 值,取最大的那個(gè)再加 1 來(lái)更新 dp[i]
  • 最后整個(gè)序列的最長(zhǎng)遞增子序列長(zhǎng)度就是 dp 數(shù)組中的最大值。

缺點(diǎn)

  • 這種常規(guī)解法的時(shí)間復(fù)雜度是 ,當(dāng)輸入序列長(zhǎng)度 n 較大時(shí),效率會(huì)比較低
  • 所以需要進(jìn)行優(yōu)化來(lái)降低時(shí)間復(fù)雜度,提升求解效率

二、優(yōu)化解法一:貪心 + 二分查找(時(shí)間復(fù)雜度優(yōu)化至nlogn )

1. 貪心思想

維護(hù)一個(gè)數(shù)組 tail,它用來(lái)存儲(chǔ)當(dāng)前找到的最長(zhǎng)遞增子序列的 “尾巴” 元素,這個(gè)數(shù)組的長(zhǎng)度其實(shí)就代表了當(dāng)前找到的最長(zhǎng)遞增子序列的長(zhǎng)度(初始時(shí)長(zhǎng)度為 0)。

對(duì)于新遍歷到的元素 nums[i],我們希望以一種貪心的策略把它盡可能合理地添加到 tail 數(shù)組中,使得 tail 數(shù)組始終保持一種有序的狀態(tài)(因?yàn)檫f增子序列的特性決定了 “尾巴” 元素是有序遞增的),這樣就能通過(guò)后續(xù)的操作高效地找到最長(zhǎng)遞增子序列。

2. 二分查找的運(yùn)用

每當(dāng)遍歷到一個(gè)新元素 nums[i] 時(shí),我們?cè)?tail 數(shù)組中通過(guò)二分查找找到第一個(gè)大于等于 nums[i] 的元素位置 pos(可以利用 Java 中的 Arrays.binarySearch 等二分查找相關(guān)方法實(shí)現(xiàn),若沒(méi)找到則返回插入點(diǎn),即合適的位置)。

  • 如果 pos 等于 tail 數(shù)組當(dāng)前長(zhǎng)度,說(shuō)明 nums[i] 比當(dāng)前所有的 “尾巴” 元素都大,那它就可以作為新的 “尾巴” 元素添加到 tail 數(shù)組末尾,使得最長(zhǎng)遞增子序列長(zhǎng)度加 1,即 tail = Arrays.copyOf(tail, tail.length + 1); tail[tail.length - 1] = nums[i];。
  • 如果 pos 小于 tail 數(shù)組當(dāng)前長(zhǎng)度,說(shuō)明 nums[i] 可以替換掉 tail[pos],因?yàn)檫@樣做不會(huì)破壞遞增子序列的性質(zhì),而且有可能在后續(xù)找到更長(zhǎng)的遞增子序列,即 tail[pos] = nums[i];

3. Java 代碼示例

import java.util.Arrays;

public class LongestIncreasingSubsequence {
    public static int lengthOfLIS(int[] nums) {
        int[] tail = new int[nums.length];
        int len = 0;
        for (int num : nums) {
            int pos = Arrays.binarySearch(tail, 0, len, num);
            if (pos < 0) {
                pos = -(pos + 1);
            }
            tail[pos] = num;
            if (pos == len) {
                len++;
            }
        }
        return len;
    }

    public static void main(String[] args) {
        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
        int result = lengthOfLIS(nums);
        System.out.println("最長(zhǎng)遞增子序列長(zhǎng)度為: " + result);
    }
}

在上述代碼中:

  • lengthOfLIS 方法實(shí)現(xiàn)了優(yōu)化后的最長(zhǎng)遞增子序列求解邏輯。通過(guò)不斷遍歷輸入數(shù)組 nums,利用二分查找在 tail 數(shù)組中定位合適位置來(lái)更新 tail 數(shù)組,同時(shí)維護(hù)最長(zhǎng)遞增子序列的長(zhǎng)度 len。
  • main 方法進(jìn)行簡(jiǎn)單測(cè)試,傳入示例數(shù)組并輸出最終計(jì)算得到的最長(zhǎng)遞增子序列長(zhǎng)度。

三、優(yōu)化解法二:動(dòng)態(tài)規(guī)劃 + 狀態(tài)壓縮(時(shí)間復(fù)雜度仍為O(n^2) ,但空間復(fù)雜度優(yōu)化)

1. 思路

原始動(dòng)態(tài)規(guī)劃解法中我們使用了一個(gè) dp 數(shù)組來(lái)記錄以每個(gè)元素為結(jié)尾的最長(zhǎng)遞增子序列長(zhǎng)度,但是其實(shí)在計(jì)算 dp[i] 時(shí),我們只需要知道前面元素中小于 nums[i] 的那些元素對(duì)應(yīng)的 dp 值情況,并不需要把所有之前元素對(duì)應(yīng)的 dp 值都完整保存下來(lái)。

所以可以通過(guò)狀態(tài)壓縮,只使用一個(gè)長(zhǎng)度為 n 的一維數(shù)組來(lái)模擬動(dòng)態(tài)規(guī)劃過(guò)程,每次更新當(dāng)前元素對(duì)應(yīng)的 dp 值時(shí),及時(shí)覆蓋之前不再需要的值,從而節(jié)省空間。

2. Java 代碼示例

public class LongestIncreasingSubsequence {
    public static int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        int maxLen = 1;
        for (int i = 0; i < n; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }

    public static void main(String[] args) {
        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
        int result = lengthOfLIS(nums);
        System.out.println("最長(zhǎng)遞增子序列長(zhǎng)度為: " + result);
    }
}

在這個(gè)代碼示例中:

  • lengthOfLIS 方法里,通過(guò)一個(gè)一維的 dp 數(shù)組來(lái)進(jìn)行動(dòng)態(tài)規(guī)劃求解,內(nèi)層循環(huán)中不斷更新 dp[i] 的值,并且實(shí)時(shí)維護(hù)最大的最長(zhǎng)遞增子序列長(zhǎng)度 maxLen,最后返回 maxLen 作為結(jié)果。
  • main 方法同樣是用于簡(jiǎn)單的測(cè)試場(chǎng)景,展示如何調(diào)用 lengthOfLIS 方法并輸出結(jié)果。

通過(guò)這些優(yōu)化解法,可以更高效地解決最長(zhǎng)遞增子序列問(wèn)題,在不同的應(yīng)用場(chǎng)景和數(shù)據(jù)規(guī)模下根據(jù)實(shí)際需求選擇合適的優(yōu)化方式來(lái)提升算法性能。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java多線程模擬搶紅包功能

    java多線程模擬搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了java多線程模擬搶紅包功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java查看變量的數(shù)據(jù)類型的三種方法

    Java查看變量的數(shù)據(jù)類型的三種方法

    Java是一門強(qiáng)類型的編程語(yǔ)言,它對(duì)變量的數(shù)據(jù)類型有嚴(yán)格的限定,在定義變量時(shí)必須聲明變量的數(shù)據(jù)類型,在為變量賦值時(shí)必須賦予與變量同一種類型的值,否則程序會(huì)報(bào)錯(cuò), 所以本文給大家介紹了Java查看變量的數(shù)據(jù)類型的三種方法,需要的朋友可以參考下
    2024-10-10
  • SpringBoot服務(wù)器端解決跨域問(wèn)題

    SpringBoot服務(wù)器端解決跨域問(wèn)題

    這篇文章主要介紹了SpringBoot服務(wù)器端解決跨域問(wèn)題,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • 詳解Spring Boot最核心的27個(gè)注解,你了解多少?

    詳解Spring Boot最核心的27個(gè)注解,你了解多少?

    這篇文章主要介紹了詳解Spring Boot最核心的27個(gè)注解,你了解多少?文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜

    Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜

    這篇文章主要介紹了Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 簡(jiǎn)單了解Spring Bean常用注解的裝配

    簡(jiǎn)單了解Spring Bean常用注解的裝配

    這篇文章主要介紹了簡(jiǎn)單了解Spring Bean常用注解的裝配,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • MyBatis中的mapper.xml配置教程

    MyBatis中的mapper.xml配置教程

    這篇文章主要介紹了MyBatis中的mapper.xml配置,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • 如何解決redisTemplate注入為空問(wèn)題

    如何解決redisTemplate注入為空問(wèn)題

    這篇文章主要介紹了如何解決redisTemplate注入為空問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Spring-ImportSelector接口功能使用案例

    Spring-ImportSelector接口功能使用案例

    ImportSelector接口是至spring中導(dǎo)入內(nèi)部類或者外部類的核心接口,只需要其定義的方法內(nèi)返回需要?jiǎng)?chuàng)建bean的class字符串就好了,這篇文章主要介紹了Spring-ImportSelector接口功能介紹,需要的朋友可以參考下
    2023-09-09
  • 淺談TreeSet中的兩種排序方式

    淺談TreeSet中的兩種排序方式

    下面小編就為大家?guī)?lái)一篇淺談TreeSet中的兩種排序方式。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05

最新評(píng)論