LeetCode 300. Longest Increasing Subsequence
问题描述
给定一个未排序的整数数组,找出最长的递增子序列。
栗子:
注意:
可能存在多种最长递增子序列的组合,只需要返回其长度即可。
算法时间复杂度需要在
O(n2)
之内。
解题思路
从上面的栗子,我们可以看出,递增子序列不要求连续。
开门见山,直接说下这道题的解法,即动态规划。使用动态规划的思想,在已有结果基础上,计算当前结果。
拿上述栗子举例,[10,9,2,5,3,7,101,18]
,我们从后往前逐个分析。
为什么要从后往前呢?因为对于我来说这样看起来更直观。当然从前往后也是可行的,当你理解了思想后,可以尝试着从前往后再推导一遍。只不过有些许差别。
从后往前,记录的是以这个数开始的递增子序列的长度。
从前往后,记录的是以这个数结束的递增子序列的长度。
弄清楚上述差别后,再加上下面的逐步推导说明,相信你也能弄明白如何从前往后分析。
下面我们对数字逐个进行分析。将 f(n)
记为从数字 n
开始的最大递增子序列长度。
18
。从它开始的递增子序列只有它本身,那么f(18) = 1
。
101
。其后没有比它大的数字,那么从它开始的递增子序列也只有它自己,f(101) = 1
。
7
。101
和18
都比它大,那它跟谁组合在一起更长呢?很简单,只需取f(101)
和f(18)
中的最大值,再加上它自身的长度1
,即f(7) = max(f(101), f(18)) + 1 = 2
。
3
。7、101、18
比它大,同理,取三者中的最大值,再加上它本身,即f(3) = max(f(7), f(101), f(18)) + 1 = 3
。
5
。7、101、18
比它大,同样需要取三者最大值,f(5) = max(f(7), f(101), f(18)) + 1 = 3
。
2
。5、3、7、101、18
比它大,同样取这几个中的最大值,f(2) = max(f(5), f(3), f(7), f(101), f(18)) + 1 = 4
。
9
。101、18
比它大,f(9) = max(f(101), f(18)) + 1 = 2
。
10
。101、18
比它大,f(10) = max(f(101), f(18)) + 1 = 2
。
不知从上面的推导过程中,你有没有发现一些规律?
当计算某个数字的最长递增子序列长度时,根据所有比其大的数字的结果,取出最大值,然后再加上它本身长度 1
,即可得出结果。当然,也可能存在根本没有比它大的数字,那么结果就是 1
。
所以,解题思路总结如下:
对于某个数来说,如果其后没有比其大的数,那么长度为
1
。如果有比它大的数,那么取所有大于它的数的结果最大值,再加
1
。用数学公式表示如下:
在上述过程中,我们可以计算出以每个数字开始的最长递增子序列长度,那么整体的最长递增子序列长度也自然很好求出。
下面给出 js
代码实现,可以对照着看一下。
版权声明: 本文为 InfoQ 作者【liu_liu】的原创文章。
原文链接:【http://xie.infoq.cn/article/01c07add856d883da2307652b】。文章转载请联系作者。
评论