NlogN中最长的子序列长度。[了解Algo]

时间:2017-12-10 08:15:37

标签: algorithm sorting binary-search correctness

问题陈述:目的是在nlogn时间内找到增长最长的子序列(不连续)。

算法:我理解这里解释的算法: http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/

我不明白的是在以下代码中存储在尾部的内容。

int LongestIncreasingSubsequenceLength(std::vector<int> &v) {
if (v.size() == 0)
    return 0;

std::vector<int> tail(v.size(), 0);
int length = 1; // always points empty slot in tail

tail[0] = v[0];
for (size_t i = 1; i < v.size(); i++) {
    if (v[i] < tail[0])
        // new smallest value
        tail[0] = v[i];
    else if (v[i] > tail[length-1])
        // v[i] extends largest subsequence
        tail[length++] = v[i];
    else
        // v[i] will become end candidate of an existing subsequence or
        // Throw away larger elements in all LIS, to make room for upcoming grater elements than v[i]
        // (and also, v[i] would have already appeared in one of LIS, identify the location and replace it)
        tail[CeilIndex(tail, -1, length-1, v[i])] = v[i];
}

return length;
}

例如,如果输入为{2,5,3 ,,,11,8,10,13,6}, 代码给出的正确长度为6。 但尾部将存储2,3,6,8,10,13。

所以我想了解尾巴中存储的是什么?。这将有助于我理解这个算法的正确性。

2 个答案:

答案 0 :(得分:2)

tail[i]是长度为i+1的递增子序列(IS)的最小结束值。

这就是为什么tail[0]是最小值&#39;以及为什么当当前值大于当前最长序列的结束值时,我们可以增加LIS(length++)的值。

假设您的示例是输入的起始值:

输入= 2,5,3,7,11,8,10,13,6 ......

我们的算法9的{​​{1}}步骤后如下所示:
tail = 2,3,6,8,10,13,......

tail的含义是什么?这意味着长度为tail[2]的最佳IS以3结尾。我们可以构建一个长度为tail[2]的IS,使用大于4的数字来扩展它。

tail[2]tail[0] = 2 2 ,5,3,7,11,8,10,13,6 IS length = 1tail[1] = 3 2 ,5, 3 ,7,11,8,10,13,6
IS length = 2tail[2] = 6 2 ,5, 3 ,7,11,8,10,13, 6 < / EM>
IS length = 3tail[3] = 8 2 ,5, 3 7 ,11, 8 ,10,13,6 IS length = 4tail[4] = 10 2 ,5, 3 7 ,11, 8 10 ,13,6 IS length = 5tail[5] = 13 2 ,5, 3 7 ,11, 8 10 13 ,6

此演示文稿允许您使用二进制搜索(请注意,IS length = 6的已定义部分始终已排序)以更新tail并在算法结束时查找结果。

答案 1 :(得分:0)

Tail srotes the Longest Increase Subsequence(LIS)。

它会根据您提供并声称已理解的链接中的说明自行更新。检查示例。

你想要尾部第一个元素的最小值,这解释了第一个if语句。

第二个if语句允许LIS增长,因为我们希望最大化其长度。