此问题在此处已有答案:
Finding All possible Longest Increasing subsequence(4个答案)
5天前关闭。
给定一个数组(向量)序列。我需要一个方法或一个修复可能会找到所有与最长递增序列长度的递增连续性。例如:**[1,3,2,5,2]**应该输出:1 3 5和1 2 5
1 3 5是第一个LIS长度3。然后下一个是1 2 5。
我已经实现了一些它适用于较小示例的东西,但一旦我有一个较大的序列数组(大小:1000+),程序就永远需要。
这是我的LIS长度的函数:它使用动态编程,工作速度非常快
int findLISLength(const std::vector<int>& sequence, size_t n) {
std::vector<int> lisEnd(n + 1, 0);
std::vector<int> parent(n, 0);
int length = 0;
for (int i = 0; i < n; ++i) {
int low = 1;
int high = length;
while (low <= high) {
int mid = (low + high) / 2;
if (sequence[lisEnd[mid]] < sequence[i])
low = mid + 1;
else
high = mid - 1;
}
int pos = low;
parent[i] = lisEnd[pos - 1];
lisEnd[pos] = i;
if (pos > length)
length = pos;
}
return length;
}
字符串
这是我的函数,用于查找给定长度的所有递增的连续性。这是时间复杂度非常高的地方,因为有三个for循环。我也尝试了递归,它需要同样多的时间。
std::vector<std::vector<int>> getAllIncreasingSubsequences(const std::vector<int>& sequence, size_t length) {
std::vector<std::vector<int>> result;
std::vector<std::vector<std::vector<int>>> dp(sequence.size());
for (size_t i = 0; i < sequence.size(); ++i) {
dp[i].push_back({ sequence[i] });
for (size_t j = 0; j < i; ++j) {
if (sequence[i] > sequence[j]) {
for (const auto& subseq : dp[j]) {
if (subseq.size() + 1 <= length) {
auto newSeq = subseq;
newSeq.push_back(sequence[i]);
dp[i].push_back(newSeq);
}
}
}
}
}
for (const auto& subseq : dp) {
for (const auto& sub : subseq) {
if (sub.size() == length) {
result.push_back(sub);
}
}
}
return result;
}
型
我从文件中读取序列号,然后调用函数。
序列为:
[43629 88099 89706 22748 1174 68526 8869 61079 64279 2965 56809 3540 94669 72740 94999 18126 ...]
int main(){
size_t L = findLISLength(sequence, N);
vector<vector<int>>
increasingSubsequences = getAllIncreasingSubsequences(sequence, L);
//print subsequence
cout << "L: " << L << endl;
cout << "Increasing subsequences: " << endl;
for (auto& subsequence : increasingSubsequences) {
for (auto& element : subsequence) {
cout << element << " ";
}
cout << '\n';
}
}
型
1条答案
按热度按时间uz75evzq1#
我不知道你的代码是如何工作的,所以我决定用一种对我来说既清楚又相当有效的方式重写。如果答案是
m
从长度为n
的列表中增加长度为k
的序列,我的算法将是O(n^2 + m*k)
。注意
m
可以随着向量的大小呈指数增长。最坏的情况是一个结构为[2, 1, 4, 3, 6, 5, 8, 7, ..., n, n-1]
的向量,那么将有2^(n/2)
最大递增序列。递增序列的数量几乎可以肯定是你的代码太慢的原因。这就是为什么我边走边打印的原因。前两行给出了它有多糟糕的想法。这是一个演示程序。
字符串