300.最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
使用动态规划算法求解
动态规划三要素:
- 重叠子问题
- 最优子结构(可以从子问题的最优结果推出更大规模问题的最优结果)
- 状态转移方程
输入数组为
n
u
m
s
nums
nums,
d
p
dp
dp 数组中,
d
p
[
i
]
dp[i]
dp[i] 表示以
n
u
m
s
[
i
]
nums[i]
nums[i] 结尾的最长上升子序列的长度。以第
i
i
i 个数结尾的最长上升子序列的长度,可由以第
1
,
2
,
.
.
.
,
i
−
1
1,2, ... ,i-1
1,2,...,i−1 个数结尾的最长上升子序列长度中最大的数加1得到。
d
p
[
i
]
=
max
(
d
p
[
i
]
,
d
p
[
j
]
+
1
)
j
=
1
,
2
,
.
.
.
,
n
−
1
dp[i] = \max(dp[i], dp[j]+1)\\ j = 1,2, ... ,n-1\\
dp[i]=max(dp[i],dp[j]+1)j=1,2,...,n−1
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
# 考虑 nums 为空序列的情况
if len(nums) == 0:
return 0
# dp 表示以 nums[i] 结尾的最长上升序列长度,初始化为全 1 序列
dp = [1 for i in range(len(nums))]
# dp[i] = max(dp[i], dp[j]+1) j = 1, 2, ... , i-1
for i in range(len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
参考: