Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18]
,
The longest increasing subsequence is [2, 3, 7, 101]
, therefore the length is 4
. Note that there may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.
Follow up: Could you improve it to O(n log n) time complexity?
长度为N的数组记为A={a0 a1 a2...an-1};
记A的前i个字符构成的前缀串为Ai= a0 a 1a2...ai-1,以ai结尾的最长递增
子序列记做Li,其长度记为a[i];
假定已经计算得到了a[0,1…,i-1],如何计算a[i]呢?
根据定义, Li必须以ai结尾,如果将ai缀到L0 L1…… Li-1的后面,是否
允许呢?
如果aj<ai,则可以将ai缀到Lj的后面,并且使得Lj的长度变长。
从而:a[i]={max(a(j))+1, 0 ≤j≤i-1且a[j]≤a[i] }
需要遍历在i之前的所有位置j,找出满足条件a[j]≤a[i]的a[j];
计算得到a[0…n-1]后,遍历所有的a[i],找出最大值即为最大递增子序列
的长度。
时间复杂度为O(N2)。
思考:如何求最大递增子序列本身?
记录前驱
1 class Solution { 2 public int lengthOfLIS(int[] a) { 3 if(a.length==0) return 0; 4 int[] longs = new int[a.length]; 5 for(int i = 0;i<a.length;i++) 6 longs[i] = 1; 7 int max = longs[0]; 8 for(int i = 1;i < a.length;i++){ 9 for(int j = 0;j <= i-1;j++) 10 if(a[j]<a[i]) 11 if(longs[i]<longs[j]+1) 12 longs[i] = longs[j]+1; 13 //如果求序列本身,在这里记录前驱 14 15 if(max<longs[i]) 16 max = longs[i]; 17 } 18 return max; 19 }
1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& a) { 4 if (a.size()==0) return 0; 5 int max = 1; 6 vector<int> dp(a.size(),1); 7 for (int i = 1 ;i < a.size(); i++) { 8 for (int j = 0; j < i ;j++) { 9 if (a[j] < a[i]) { 10 dp[i] = std::max(dp[j]+1,dp[i]); 11 } 12 } 13 max = std::max(dp[i],max); 14 } 15 16 return max; 17 } 18 };
1 class Solution(object): 2 def lengthOfLIS(self, a): 3 n = len(a) 4 if n ==0: 5 return 0 6 dp = [1] * n 7 for i in range(n): 8 for j in range(i): 9 if(a[i]>a[j] and dp[i]<dp[j]+1): 10 dp[i] = dp[j]+1 11 12 #dp[i]现在存储的即为以a[i]结尾最长递增子序列长度 13 #求dp数组中最大者即为最长的长度 14 15 return max(dp)