【发布时间】:2011-10-20 08:55:19
【问题描述】:
这不是家庭作业问题。我正在复习最长递增子序列问题。我在网上阅读了每一个地方。我了解如何找到“长度”,但我不明白如何回溯实际序列。我正在使用耐心排序算法来查找长度。谁能解释如何找到实际的序列?我不太了解维基百科中的版本。有人可以用不同的方法或不同的方式解释吗?
谢谢。
【问题讨论】:
这不是家庭作业问题。我正在复习最长递增子序列问题。我在网上阅读了每一个地方。我了解如何找到“长度”,但我不明白如何回溯实际序列。我正在使用耐心排序算法来查找长度。谁能解释如何找到实际的序列?我不太了解维基百科中的版本。有人可以用不同的方法或不同的方式解释吗?
谢谢。
【问题讨论】:
让我们将 max(j) 定义为直到 A[j] 的最长递增子序列。有两种选择:或者我们在这个子序列中使用 A[j],或者我们不使用。
如果我们不使用它,那么该值将是 max(j-1)。如果我们确实使用它,那么值将是 max(i)+1,当 i 是满足 i
综上所述,计算 max(j) 的递归公式为: max{max(j-1),max*(i)+1},max*(j)= max*(i)+1。 在每个数组单元格中,您可以保存一个指针,它会告诉您是否选择使用 A[j] 单元格。 这样你可以在数组上向后移动的同时找到所有的序列。
时间复杂度:递归公式和最后找到序列的复杂度是O(n)。这里的问题是为每个 A[j] 找到相应的 A[i],使得 i 是最大的索引,使得 i
*排序你的数组。 1)求数组中最小的整数,记为数组中的位置为k。
2)对于 A[k+1],我们当然有 A[k] A[k+2],那么 k 也会到达 k+2 单元,以此类推,直到 A[k+m]
3)删除你在上一阶段找到对应单元格的所有单元格
4) 返回到 1。
希望对您有所帮助。 请注意,我是独自考虑的,因此这里有一些错误的可能性很小-如果您需要,请相信我是对的,并要求更多澄清。
【讨论】:
此 Python 代码解决了最长递增序列问题,并且还返回了其中一个此类序列。诀窍是,在填充动态规划表的同时,另一个数组也被填充,存储用于构造最优解的元素的索引。
def an_lis(nums):
table, solution = lis_table(nums)
if not table:
return (0, [])
n, maxLen = max(enumerate(table), key=itemgetter(1))
lis = [nums[n]]
while solution[n] != -1:
lis.append(nums[solution[n]])
n = solution[n]
return lis[::-1]
def lis_table(nums):
n = len(nums)
table, solution = [0] * n, [-1] * n
for i in xrange(n):
maxLen, maxIdx = 0, -1
for j in xrange(i):
if nums[j] < nums[i] and table[j] > maxLen:
maxLen, maxIdx = table[j], j
table[i], solution[i] = 1 + maxLen, maxIdx
return (table, solution)
【讨论】: