我有一个整数数组A [1 ... N]。现在我想要打印所有最长的减少后续数据。我已经完成了大部分教程,但是所有教程只打印了一个LDS。假设LDS的长度是5,那么大多数只打印一个长度为5的LDS。 但我想打印所有可能的LDS。如何做到这一点?可以在O(nlongn)时间内完成。伪代码将更有帮助。
答案 0 :(得分:1)
您可以随时跟踪所有最长(到目前为止)的子序列:
// If you have only one element, that is the longest descending subsequence
// Otherwise store first element as previous
if: current element is less than (or equal to) previous
// decreasing
increase current subsequence length
add element to current subsequence
else:
// increasing
set current subsequence length to 0
empty current subsequence
if: current subsequence is longer than current maximum
invalidate all current max subsequences
set current maximum subsequence length to current subsequence length
add current subsequence to set of longest subsequences
else if: current subsequence is same size as current maximum
add current subsequence to set of longest subsequences
答案 1 :(得分:1)
如果您从教程中取消优化算法,并使用更简单的N^2
算法进行线性搜索而不是在地图中查找,则更容易理解这个想法。然后修改打印序列的代码以向后搜索先前元素,而不是将其存储在vector<int> pre
中。然后你可以用一个简单的递归回溯器打印所有序列:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print_all(
const vector<int> seq
, const vector<int>& len
, int max, int pos
, vector<int>& sofar) {
if (max == 0) {
for (int i = sofar.size()-1 ; i >= 0 ; i--)
cout << sofar[i] << " ";
cout << endl;
return;
}
int val = pos < seq.size() ? seq[pos] : -1;
for (int i = pos-1 ; i >= 0 ; i--) {
if (len[i] == max && seq[i] > val) {
sofar.push_back(seq[i]);
print_all(seq, len, max-1, i, sofar);
sofar.erase(sofar.end()-1);
}
}
}
int main() {
int data[] = {5, 30, 2, 17, 92, 11, 7, 10, 2, 1};
vector<int> seq(data, data+10);
vector<int> len(seq.size());
for (int i = 0 ; i < seq.size() ; i++) {
len[i] = 1;
for (int j = i-1 ; j >= 0 ; j--)
if (seq[j] > seq[i] && len[j]+1 > len[i])
len[i] = len[j]+1;
}
int max = *max_element(len.begin(), len.end());
cerr << max << endl;
vector<int> sofar;
print_all(seq, len, max, seq.size(), sofar);
}