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?
假设输入数组的input长度为n,则构建一个具有n个元素的数组dp,在这个数组中第i个元素表示:以input的第i个元素为最长递增子序列的最后一个元素,最长递增子序列的长度为dp [ i ]。
对于第1个元素,则有dp [ 1 ] = 1;
对于第i + 1个元素,将其与前 i 个元素比较,如果第 j 个元素小于第 i + 1 个元素,则以第 i + 1 个元素为最后一个元素、以第 j 个元素为倒数第二个元素的最长递增子序列的长度为 dp [ j ] + 1 。
以第i个元素为最后一个元素,以第j个元素为倒数第二个元素的最长递增子序列的长度可用如下公式表示:
f ( i , j ) = input [ i ] > input [ j ] ? dp [ j ] + 1 : 1 其中 1 <= j < i
当f (i , j ) = 1 时,表示没有这样的子序列(dp [ i ] 一定是大于0的)。
当第i个元素为前i个元素的最小值时,此时的 dp [ i ] = 1,也满足上面的公式。
则dp [ i ] = max ( f ( i , 1 ) , ... ... , f ( i , j ) , ... ... f ( i , i - 1 ) , f ( i , i ) ) 1 <= j <= i
而最终的结果是
Max ( dp [ 1 ] , dp [ 2 ] , ... ... , dp[ n - 1 ] , dp [ n ] )
同样采用动态规划的方法,但此时采用的数组dp保存的数值的含义和上面不同。
(A)中间替换元素,子序列长度不变
假设前 i 个元素后,dp中已经有m个元素(递增),在考察第 i + 1个元素时,对dp进行二分查找,找到第一个大于 input [ i + 1 ] 的元素,即找到第k个元素,使得
dp [ k - 1 ] < input [ i + 1 ] < dp [ k ]
如果 ( dp [ 0 ] , dp [ 1 ] , ... ... , dp [ k - 1 ] , dp [ k ] ) 是所求最长递增子序列的一部分,则 ( dp [ 0 ] , dp [ 1 ] , ... ... , dp[ k - 1] , input [ i + 1 ] ) 一定也是最长递增子序列的一部分(子序列不同);反之,则不一定成立。
所以,根据上述推论,可以用 input [ i + 1 ] 替换掉dp的第 k 个元素。
(B)末尾添加元素,子序列长度增长
如果 input [ i + 1 ] 大于dp中的所有元素,此时在dp末尾添加一个元素input [ i + 1 ],此时:
dp中保存的元素就是前 i + 1个元素的最长递增子序列
(C)替换中间某个元素后,到达输入数组末尾
假设输入数组共有n个元素,dp共有m个元素,且在第k个元素时,dp添加了第m个元素。也就是说在第k个元素时,得到的dp就是所求的最长递增子序列。
之后,从第 k + 1 个元素到第 n 个元素,dp没有新元素在末尾添加,但有可能发生了元素的替换。
到了输入数组末尾后,此时的dp中保存的不是最长递增子序列,但其长度和最长递增子序列相同。
(D)数组初始条件
在输入数组第1个元素,将 input[ 1 ] 插入数组dp末尾,此时的处理办法与(B)中的相同,故初始状态:dp为空数组,从输入数组第1个元素开始处理。
Given an unsorted array of integers, find the number of longest increasing subsequence.
解决方案:
采用上面问题中的解决方案(1),除了使用一个数组dp保存以第i个元素为末尾的最长子序列的长度外,额外使用一个数组num保存以第i个元素为末尾的最长子序列的个数。
最终从dp中取得最长递增子序列的长度max后,最终的结果就是:
Σ( num[ i ] ) 其中:dp[i] = max