问题陈述:目的是在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。
所以我想了解尾巴中存储的是什么?。这将有助于我理解这个算法的正确性。
答案 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 = 1
,tail[1] = 3
: 2 ,5, 3 ,7,11,8,10,13,6
IS length = 2
,tail[2] = 6
: 2 ,5, 3 ,7,11,8,10,13, 6 < / EM> 强>
IS length = 3
,tail[3] = 8
: 2 ,5, 3 , 7 ,11, 8 ,10,13,6
IS length = 4
,tail[4] = 10
: 2 ,5, 3 , 7 ,11, 8 , 10 ,13,6
IS length = 5
,tail[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增长,因为我们希望最大化其长度。