📅  最后修改于: 2023-12-03 15:11:53.698000             🧑  作者: Mango
有一个数组,需要找到严格递增子序列(即LIS),并将其拼接起来形成一个最小的串联结果。
这道题可以使用动态规划来解决。具体来说,我们可以定义一个dp数组,其中dp[i]表示以nums[i]作为结尾的最长递增子序列的长度。那么,对于第i个位置,我们需要判断它前面的所有位置中哪些位置的值比nums[i]小,然后找出这些位置的dp值中最大的那个,再将这个最大的dp值加一得到dp[i],即:
dp[i] = max(dp[j] + 1), 其中 0 ≤ j <i 且 nums[j] <nums[i]。
最后,我们只需要找到dp数组中的最大值,即为所求的LIS长度。
接下来的问题是如何构造最小的串联结果。我们可以在DP的同时,记录dp[i]的来源位置,即dp[j] + 1 ==dp[i]的j。这样,当我们求出dp数组的最大值时,我们就可以从该位置开始,倒序遍历dp数组,找到所有来源位置,将相应的值拼接起来,即为所求的最小的串联结果。
def min_concat(nums):
n = len(nums)
dp = [1] * n
pre = [-1] * n # 记录dp[i]的来源位置
for i in range(1, n):
for j in range(i):
if nums[j] < nums[i] and dp[j] + 1 > dp[i]:
dp[i] = dp[j] + 1
pre[i] = j
max_len = max(dp)
end = dp.index(max_len)
ans = [nums[end]]
while pre[end] != -1:
ans.append(nums[pre[end]])
end = pre[end]
return "".join(map(str, ans[::-1]))
assert min_concat([10, 9, 2, 5, 3, 7, 101, 18]) == '2357'
assert min_concat([1, 3, 2, 4, 5, 6, 7]) == '1234567'
assert min_concat([4, 3, 2, 1]) == '4'
assert min_concat([2, 2]) == '2'