1. 程式人生 > >76 最長上升子序列

76 最長上升子序列

簡潔 markdown 當前位置 turn 給定 lis star 時間 line

原題網址:https://www.lintcode.com/problem/longest-increasing-subsequence/description

描述

給定一個整數序列,找到最長上升子序列(LIS),返回LIS的長度。

您在真實的面試中是否遇到過這個題?

說明

最長上升子序列的定義:

最長上升子序列問題是在一個無序的給定序列中找到一個盡可能長的由低到高排列的子序列,這種子序列不一定是連續的或者唯一的。
https://en.wikipedia.org/wiki/Longest_increasing_subsequence

樣例

給出 [5,4,1,2,3]

,LIS 是 [1,2,3],返回 3
給出 [4,2,4,5,3,7],LIS 是 [2,4,5,7],返回 4

挑戰

要求時間復雜度為O(n^2) 或者 O(nlogn)

標簽 二分法 LintCode 版權所有 動態規劃(DP) O(n^2)思路 動態規劃,dp【i】為以 i 為終點的子數組的最長上升子序列長度。 狀態轉移方程:對每個i,遍歷其之前的動態規劃數組,即dp【j】(0<=j<i),如果nums【i】>nums【j】(保證子數組終點),dp【j】加1。然後,找到最大的dp【j】賦給dp【i】。 最後返回dp數組最大值。
AC代碼:
class Solution {
public:
    /**
     * @param nums: An integer array
     * @return: The length of LIS (longest increasing subsequence)
     */
    int longestIncreasingSubsequence(vector<int> &nums) {
        // write your code here
    int size=nums.size();
    if (size<=0)
    {
        
return 0; } vector<int> dp(size,1); int maxl=0; for (int i=1;i<size;i++) { for (int j=0;j<i;j++) { if (nums[i]>nums[j]) { dp[i]=max(dp[i],dp[j]+1);//更新dp[j],將選出最大dp[j]賦給dp[i]; } } maxl=max(maxl,dp[i]);//更新dp數組最大元素; } return maxl; } };

參考:

Lintcode--010(最長上升子序列) 講解詳細

lintcode-最長上升子序列-76 O(n ^ 2)代碼更簡潔

lintcode:最長上升子序列 講解詳細

O(nlogn)思路 LintCode 最長上升子序列 —————————————————分割線,錯誤代碼記錄———————————————— 最開始的想法是遍歷數組,將當前元素nums【i】作為子序列起始值。然後遍歷 i 之後的元素,如果比起始值大,長度就+1,同時用該元素更新起始值,進入下一次對比。最後返回子序列長度最大的。 這個思路是錯的,因為無法保證每次求得的長度是當前位置(i)上最長子序列。 如【10,11,1,12,2,11,3,10,4】,返回結果是3,而實際結果是4。 代碼:
int longestIncreasingSubsequence1(vector<int> &nums)
{
    int size=nums.size();
    if (size<=0)
    {
        return 0;
    }
    int pre;
    int len=1,result=1;
    for (int i=0;i<size;i++)
    {
        pre=nums[i];
        len=1;
        for (int j=i+1;j<size;j++)
        {
            if (nums[j]>pre)
            {
                pre=nums[j];
                len++;
            }
        }
        if (len>result)
        {
            result=len;
        }
    
    }

    return result;
}

76 最長上升子序列