📅  最后修改于: 2023-12-03 15:10:21.802000             🧑  作者: Mango
数组中的最长子序列是指一个数组中连续的一段序列,该序列中的元素可以按照任意顺序排列,但其在原始数组中的顺序必须保持不变,且所有元素均为裸数字(即没有单位或其他修饰)。
以下是一个简单的实现,使用一个动态规划数组 dp
来记录从每个元素开始的最长子序列长度。其中 dp[i]
表示以下标为 i
结尾的最长子序列长度。初始时,dp[i]
均为 1,即每个元素本身就是一个长度为 1 的子序列。然后遍历整个数组,对于每个位置 i
,内部再次遍历前面的元素 j
,如果 nums[i]
大于 nums[j]
,则可以将前面的最长子序列长度 dp[j]
加上 1,得到一个以 nums[i]
结尾的新的最长子序列长度。最后返回 dp
数组中的最大值即可。
def longest_subsequence(nums):
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
此算法的时间复杂度为 $O(n^2)$。我们还可以继续优化,使用一个辅助数组 tails
来记录目前为止已经处理过的元素中,最长的增序列。遍历整个数组时,对于每个位置 i
,使用二分查找法将其插入到 tails
数组中,保持 tails
数组始终是一个有效的增序列,同时也是已处理元素中最长的增序列,此时的 tails
数组长度即为目前为止的最长子序列长度。
def longest_subsequence(nums):
n = len(nums)
tails = [0] * n
size = 0
for num in nums:
i, j = 0, size
while i < j:
mid = i + (j - i) // 2
if tails[mid] < num:
i = mid + 1
else:
j = mid
tails[i] = num
size = max(size, i + 1)
return size
此算法的时间复杂度为 $O(n \log n)$。