📅  最后修改于: 2023-12-03 15:36:16.007000             🧑  作者: Mango
本文介绍如何在一个长度为 N 的排列中,从两端依次取数,生成两个具有相同大小的最长上升子序列(LIS)。
给定一个长度为 N 的排列,如何从两端依次取数,生成两个具有相同大小的最长上升子序列?
一种思路是从中间位置开始往两端进行扩展,直到两边能够生成相同大小的 LIS。
def get_LIS_from_both_ends(arr: List[int]) -> List[int]:
# 排序
arr = sorted(arr)
# 找到中间位置
mid = len(arr) // 2
left, right = arr[:mid], arr[mid:]
# 求左侧 LIS
dp_left = [1] * len(left)
for i in range(1, len(left)):
for j in range(i):
if left[j] < left[i]:
dp_left[i] = max(dp_left[i], dp_left[j] + 1)
# 求右侧 LIS
dp_right = [1] * len(right)
for i in range(len(right)-2, -1, -1):
for j in range(len(right)-1, i, -1):
if right[j] < right[i]:
dp_right[i] = max(dp_right[i], dp_right[j] + 1)
# 合并两个 LIS,得到一个具有相同大小的最长上升子序列
lis = []
for i in range(len(dp_left)):
if dp_left[i] == dp_right[i]:
lis = left[:i+1] + right[len(right)-i-1:]
break
return lis
本方法的时间复杂度为 O(N^2),其中 N 为排列的长度。
本文介绍了如何在一个长度为 N 的排列中,从两端依次取数,生成两个具有相同大小的最长上升子序列。这个问题可以通过从中间位置开始往两端进行扩展来解决。在得到左右两边的 LIS 之后,进行合并得到一个具有相同大小的最长上升子序列。