题目链接: https://leetcode-cn.com/problems/longest-increasing-subsequence
难度:中等
通过率:43.0%
题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 $O(n^2)$ 。
进阶: 你能将算法的时间复杂度降低到 $O(nlog n)$ 吗?
思路:
思路一:动态规划
dp[i]
表示以nums[i]
结尾的最长上升子序列
动态方程:dp[i] = max(dp[i], dp[j] + 1) j < i
时间复杂度:
空间复杂度:
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j] + 1)
#print(dp)
return max(dp or [0])
思路二:二分法
我们建立一个数组有序(递增)arr
,记录遍历的数组。
当遍历的数比arr
最后一个数还有大,添加到arr
末尾
当遍历的数比尾数小,有二分法找到arr
的位置,覆盖
最后返回arr
的长度即可。arr
数组不一定是真实的最长上升子序列。
大家可以有例子模拟一下!
时间复杂度:
空间复杂度:
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
import bisect
arr = []
for num in nums:
loc = bisect.bisect_left(arr, num)
arr[loc:loc + 1] = [num]
# print(arr)
return len(arr)
更多题解:
九四干:[LeetCode] 题目汇总(持续更新)zhuanlan.zhihu.com