题目链接: 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] * nfor 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 bisectarr = []for num in nums:loc = bisect.bisect_left(arr, num)arr[loc:loc + 1] = [num]# print(arr)return len(arr)
更多题解:
九四干:[LeetCode] 题目汇总(持续更新)zhuanlan.zhihu.com