力扣300. 最长递增子序列
每日几道leetcode刷刷题!
lc300
题目描述
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
代码
动态规划
时间复杂度:
O
(
O(
O(n^2
)
)
)
空间复杂度:
O
(
n
)
O(n)
O(n)
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
if not nums:
return 0
dp = []
for i in range(len(nums)):
dp.append(1)
for j in range(i):
## 如果要求非严格递增,将此行 '<' 改为 '<=' 即可。
if nums[i] > nums[j]: #要是比第j个大那就 dp[i] = max(dp[i], dp[j] + 1)
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
动态规划+二分法
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn), 遍历 numsnums 列表需
O
(
N
)
O
(
N
)
O(N)O(N)
O(N)O(N),在每个 nums[i]二分法需
O
(
l
o
g
N
)
O(logN)
O(logN)。
空间复杂度:
O
(
n
)
O(n)
O(n)
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
d = []
for n in nums:
if not d or n > d[-1]:
d.append(n)
else: #双指针定位
l, r = 0, len(d) - 1
loc = r
while l <= r:
mid = (l + r) // 2
if d[mid] >= n:
loc = mid
r = mid - 1
else:
l = mid + 1
d[loc] = n
return len(d)
总结
在面对最大值等极限问题,可以先考虑动态规划方法