给你一个整数数组 n u m s nums nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如, [ 3 , 6 , 2 , 7 ] [3,6,2,7] [3,6,2,7] 是数组 [ 0 , 3 , 1 , 6 , 2 , 2 , 7 ] [0,3,1,6,2,2,7] [0,3,1,6,2,2,7] 的子序列。
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
输入:nums = [7,7,7,7,7,7,7]
输出:1
定义 d p [ i ] dp[i] dp[i] 为考虑前 i i i 个元素,以第 i i i 个数字结尾的最长上升子序列的长度,注意, n u m s [ i ] nums[i] nums[i] 必须被选取。
我们从小到大计算 d p dp dp 数组中的值,在计算 d p [ i ] dp[i] dp[i] 之前,我们已经计算出 d p [ 1 , . . . , i − 1 ] dp[1,...,i-1] dp[1,...,i−1] 的值,则状态转移方程是:
d p [ i ] = m a x ( d p [ j ] ) + 1 , 其中 0 ≤ j < i 且 n u m [ j ] < n u m [ i ] dp[i]=max(dp[j])+1,其中0≤jdp[i]=max(dp[j])+1,其中0≤j<i 且num[j]<num[i]
即考虑在 d p [ 1 , . . . , i − 1 ] dp[1,...,i-1] dp[1,...,i−1] 中最长的上升子序列后面再加一个 n u m s [ i ] nums[i] nums[i]。由于 d p [ j ] dp[j] dp[j] 代表 n u m s [ 0 , . . . , j ] nums[0,...,j] nums[0,...,j] 中以 n u m s [ j ] nums[j] nums[j] 结尾的最长上升子序列,所以,如果状态能转移过来,必须 n u m [ j ] < n u m [ i ] num[j]
最后,整个数组的最长上升子序列即素有 d p [ i ] dp[i] dp[i] 中的最大值。
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
length = len(nums)
dp = [1]*(length)
dp[0] = 1
for i in range(length):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i],dp[j]+1)
return max(dp)