leetcode -[動態規劃、二分查找] - (300)最長遞增子序列LIS

1、問題描述

給定一個無序的數組,求數組中最長遞增子序列的最大長度。
一個數組可能由多個遞增子序列,求這些子序列中的最大長度。

輸入:[10,9,2,3,1,7,18]
輸出:4
解釋:最長的遞增子序列爲[2,3,7,18],其長度爲4.

2、解題思路

特殊輸入:數組爲空的情況。
解決這道問題由以下兩種方法:
方法1:動態規劃。
分析:數組numsnums的最長遞增子序列可能以nums[j](j=0,1,2,...,len1)nums[j](j = 0,1,2,...,len - 1)結尾,且一定是這lenlen個遞增子序列的長度最大的那個。
(1) 狀態定義
dp[i]dp[i]表示nums[i]nums[i]結尾的最長遞增子序列的長度。

(2) 狀態轉移
考慮dp[i]dp[i]dp[j](j=0,1,2,...,len1)dp[j](j = 0,1,2,...,len-1)之間的關係,當nums[j]<nums[i]nums[j] < nums[i],以nums[i]nums[i]結尾的最長遞增子序列的長度等於以nums[j]nums[j]結尾的最最長遞增子序列的長度加1,即
dp[i]=max{dp[j]+1}dp[i]= max\{dp[j]+1\} 其中,j={1,2,..,i1}&&nums[j]<nums[i]j= \{1,2,..,i-1\} \&\& nums[j] < nums[i]

(3) 確定起始
只有開頭一個元素時,以該元素結尾的最長遞增子序列的長度爲1,即dp[0]=1dp[0] = 1

(4)確定結束
dp[0],dp[1],...,dp[len1]dp[0],dp[1],...,dp[len-1]中的最大值即爲該數組的最長遞增子序列的長度。

3、代碼實現

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int len = nums.size();
        if(len == 0){
            return 0;
        }
        vector<int> dp(len, 0);
        dp[0] = 1;
        for(int i = 1; i < len; i++){
            int maxdpj = -1;
            for(int j = 0; j < i; j++){
                if(nums[j] < nums[i]){
                    maxdpj = max(maxdpj, dp[j]);
                }
            }
            if(maxdpj == -1){
                dp[i] = 1;
            }
            else{
                dp[i] = maxdpj + 1;
            }
            // cout<<"dp["<<i<<"]="<<dp[i]<<endl;
        }
        
        int maxlis = -1;
        for(int i = 0; i < len; i++){
            maxlis = max(maxlis, dp[i]);
        }
        return maxlis;

    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章