Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:
Input:[10,9,2,5,3,7,101,18]
Output: 4 Explanation: The longest increasing subsequence is[2,3,7,101]
, therefore the length is 4.
这是一道动态规划算法的题。
第一个想法就是建立一个数组,记录到当前数字为止的最长增加子序列(LIS)。但是这种算法速度过于缓慢,时间复杂度为O(n2).
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l=len(nums)
if l==0:return 0
dp = [1 for i in range(l)]
for i in range(l):
for j in range(i):
if nums[i]<nums[j]:
continue
if nums[i]>nums[j]:
dp[i]=max(dp[i],dp[j]+1)
return max(dp)
看完discuss后想了一会才理解另一种算法:
比如数组为[2,5,3,9,6,7,10],
我在代码中打印的tails(如下)就是
[2, 0, 0, 0, 0, 0, 0]
[2, 5, 0, 0, 0, 0, 0]
[2, 3, 0, 0, 0, 0, 0]
[2, 3, 9, 0, 0, 0, 0]
[2, 3, 6, 0, 0, 0, 0]
[2, 3, 6, 7, 0, 0, 0]
[2, 3, 6, 7, 10, 0, 0]
比如到了[2, 3, 9, 0, 0, 0, 0],下一个数是6,我们只需要把6放在正确的位置上就行,变为[2, 3, 6, 0, 0, 0, 0],
这样原LIS长度并不会改变,后面再有比6大的数长度也是+1,并不会影响后续长度计算。
也就是说,把9换成6并不会影响比9大的数继续添加到末尾,而是在再次出现6到9之间的数字时,可以添加到数组中。
class Solution(object):
def lengthOfLIS(self, nums):
tails = [0] * len(nums)
size = 0
for x in nums:
i, j = 0, size
while i != j:
m = (i + j) / 2
if tails[m] < x:
i = m + 1
else:
j = m
tails[i] = x
########### print(tails)
size = max(i + 1, size)
return size