最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于最長遞增子序列問題概述

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

一、最長遞增子序列問題概述

1. 問題定義

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

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

2. 常規(guī)動態(tài)規(guī)劃解法思路及缺點

思路

  • 通??梢远x一個 dp 數(shù)組,其中 dp[i] 表示以 nums[i] 為結尾的最長遞增子序列的長度。
  • 狀態(tài)轉(zhuǎn)移方程一般為 dp[i] = max(dp[j]) + 1(其中 0 <= j < inums[j] < nums[i]),也就是遍歷前面所有小于 nums[i] 的元素對應的 dp 值,取最大的那個再加 1 來更新 dp[i]。
  • 最后整個序列的最長遞增子序列長度就是 dp 數(shù)組中的最大值。

缺點

  • 這種常規(guī)解法的時間復雜度是 ,當輸入序列長度 n 較大時,效率會比較低
  • 所以需要進行優(yōu)化來降低時間復雜度,提升求解效率

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

1. 貪心思想

維護一個數(shù)組 tail,它用來存儲當前找到的最長遞增子序列的 “尾巴” 元素,這個數(shù)組的長度其實就代表了當前找到的最長遞增子序列的長度(初始時長度為 0)。

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

2. 二分查找的運用

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

  • 如果 pos 等于 tail 數(shù)組當前長度,說明 nums[i] 比當前所有的 “尾巴” 元素都大,那它就可以作為新的 “尾巴” 元素添加到 tail 數(shù)組末尾,使得最長遞增子序列長度加 1,即 tail = Arrays.copyOf(tail, tail.length + 1); tail[tail.length - 1] = nums[i];。
  • 如果 pos 小于 tail 數(shù)組當前長度,說明 nums[i] 可以替換掉 tail[pos],因為這樣做不會破壞遞增子序列的性質(zhì),而且有可能在后續(xù)找到更長的遞增子序列,即 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("最長遞增子序列長度為: " + result);
    }
}

在上述代碼中:

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

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

1. 思路

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

所以可以通過狀態(tài)壓縮,只使用一個長度為 n 的一維數(shù)組來模擬動態(tài)規(guī)劃過程,每次更新當前元素對應的 dp 值時,及時覆蓋之前不再需要的值,從而節(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("最長遞增子序列長度為: " + result);
    }
}

在這個代碼示例中:

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

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

總結

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

相關文章

  • Java8中l(wèi)ambda表達式的應用及一些泛型相關知識

    Java8中l(wèi)ambda表達式的應用及一些泛型相關知識

    這篇文章主要介紹了Java8中l(wèi)ambda表達式的應用及一些泛型相關知識的相關資料
    2017-01-01
  • springboot接收前端參數(shù)的四種方式圖文詳解

    springboot接收前端參數(shù)的四種方式圖文詳解

    Spring Boot可以通過多種方式接收前端傳遞的數(shù)據(jù),下面這篇文章主要給大家介紹了關于springboot接收前端參數(shù)的四種方式,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Java中StopWatch的使用示例詳解

    Java中StopWatch的使用示例詳解

    stopWatch 是org.springframework.util 包下的一個工具類,使用它可直觀的輸出代碼執(zhí)行耗時,以及執(zhí)行時間百分比,這篇文章主要介紹了Java中StopWatch的使用詳解,需要的朋友可以參考下
    2025-04-04
  • JavaWeb中異步交互的關鍵Ajax詳解

    JavaWeb中異步交互的關鍵Ajax詳解

    這篇文章主要給大家介紹了關于JavaWeb中異步交互關鍵Ajax的相關資料,在javaweb中,ajax是前后臺交互的技術,可以實現(xiàn)異步請求,不用刷新整個頁面就可以完成操作,需要的朋友可以參考下
    2023-07-07
  • RedisTemplate默認序列化方式顯示中文亂碼的解決

    RedisTemplate默認序列化方式顯示中文亂碼的解決

    本文主要介紹了SpringDataRedis默認使用JdkSerializationRedisSerializer導致數(shù)據(jù)亂碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-06-06
  • Java?方法(方法的定義,可變參數(shù),參數(shù)的傳遞問題,方法重載,方法簽名)

    Java?方法(方法的定義,可變參數(shù),參數(shù)的傳遞問題,方法重載,方法簽名)

    這篇文章主要介紹了Java?方法(方法的定義,可變參數(shù),參數(shù)的傳遞問題,方法重載,方法簽名),文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-09-09
  • java類的組成結構詳解

    java類的組成結構詳解

    大家好,本篇文章主要講的是java類的組成結構詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法

    java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法

    這篇文章主要介紹了java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • 詳解JAVA中priorityqueue的具體使用

    詳解JAVA中priorityqueue的具體使用

    這篇文章主要介紹了詳解JAVA中priorityqueue的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • Java數(shù)組的運用詳解

    Java數(shù)組的運用詳解

    這篇文章主要給大家介紹了關于Java中數(shù)組的定義和使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08

最新評論

阿拉善盟| 阿图什市| 萨嘎县| 阜城县| 杭锦后旗| 张家港市| 金山区| 萝北县| 二手房| 虎林市| 肥西县| 含山县| 阜宁县| 乌鲁木齐市| 萝北县| 油尖旺区| 镇沅| 荔波县| 廉江市| 上虞市| 博乐市| 万年县| 新巴尔虎右旗| 青阳县| 朝阳区| 罗平县| 宣汉县| 九台市| 化州市| 通州区| 新泰市| 福海县| 绥芬河市| 白玉县| 裕民县| 兴和县| 邹平县| 安顺市| 恭城| 台安县| 谷城县|