这是最长递增子序列问题的变体。假设您不想找到一个序列或计算有多少个序列,而是想识别可能是某个最长递增序列的一部分的项目。
例如,在列表中,1,2,4,3,0,5
除零之外的所有项目都可以是最长递增子序列的一部分。
找到这些项目的策略是什么?它的效率如何?
一种方法是使用与最长递增子序列问题相同的动态算法,i
假设它是最后一个项目,跟踪最好的项目在第 'th 项目之前,但对其进行调整以跟踪关系。然后,在已知每个项目的最佳先前项目之后,确定从得分最高的项目开始时可以通过该图到达哪些项目。
在示例的情况下1,2,4,3,0,5
,它会像这样工作:
1
位于索引 0 处,因此在没有先前索引的情况下给它 1 的 lis 分数2
前面可以有1
,所以2
得到 1+1=2 的 lis 分数和 0 的前一个索引4
可以在2
and之前1
,但2
具有更好4
的 lis 得分,因此获得 2+1=3 的 lis 得分和之前的索引 13
也可以在 and 之前2
,1
并且再次2
具有更好3
的 lis 分数,因此获得 2+1=3 的 lis 分数和之前的索引 10
前面不能有任何东西,所以它的 lis 分数为 1,没有先前的索引 5
可以在任何其他项目之前,但3
具有4
最佳 lis 分数 (=3),因此5
获得 lis 分数为 3+1=4,之前的索引为 2 或 3。现在我们取得分最高的项目,就5
在这种情况下,并迭代地向后搜索可以在它之前的项目。5
这会将、3
、4
和2
(1
但不是)标记0
为可以在最长序列中。
这绝对是O(n^2)
及时的,我认为通过聪明它可以及时工作O(n lg n)
。
从二次时间开始的主要挑战不是制作具有“可以优化地优先于”边的显式图。像这样的列表1,1,1,1,1,1,...,2,2,2,2,2,2,...
具有二次边数,因此您需要避免将它们全部存储或全部探索。