题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度,并输出序列。
示例:
输入:[10,9,2,5,3,7,101,18]
输出:4
动态规划O(n2),dp[i]表示以第i个元素作为子序列的最后一个元素所能组成的最长的递增子序列的最长长度。
class Solution:
def lengthOfLIS(self, num):
length = len(num)
dp = [1]*length
pre = [-1]*length
for i in range(1, length):
for j in range(i):
if num[i] > num[j] and dp[j] + 1 >dp[i]:
dp[i] = dp[j] + 1
pre[i] = j#pre数组记录每一个 i 的前驱元素,方便记录序列
_max = 1
idx = 0
for i in range(length):
if dp[i] > _max:
_max = dp[i]
idx = i
print(_max)
result = []
while pre[idx] != -1:
result.append(num[idx])
idx = pre[idx]
result.append(num[idx])
print(result[::-1])
二分 O(nlogn)算法,dp[i]表示长度为i 的序列的最后一个元素。
class Solution:
def lengthOfLIS(self, num):
length = len(num)
dp = []
dp.append(num[0])
for i in range(1, length):
if num[i] > dp[-1]:
dp.append(num[i])
elif num[i] <= dp[0]:
dp[0] = num[i]
else:#dp[0] < num[i] <=dp[-1],二分查找
low = 0
high = len(dp)
while low < high:
mid = int((low + high) / 2)
if dp[mid] > num[i]:
high = mid
else:#dp[mid] < num[i]
low = mid + 1
dp[low] = num[i]
print(len(dp))
print(dp)