示例:给定[1 2 3 10 7 8 9],我正在寻找一种给出[1 1 1 0 1 1 1]的算法。
我有一个未排序的数组作为输入。作为输出,我寻找最大的排序选择。
最坏的情况:我必须尝试所有2 ^ {0,1}个可能的选择。有没有更快的算法可以做到这一点?我不记得CS学习中的任何内容,也无法在线找到任何内容(至少使用我的措辞)。
答案 0 :(得分:1)
是的,这可以通过动态编程解决。
您必须创建另一个长度等于给定数组的对数组,让我们将其命名为arr
arr [index]将存储子数组的最大长度,从而如果考虑到namedArray [0 ... index]中的数组及其后的namedArray [index]元素,则givenArray [index]是排序后的最后一个元素已添加。
从arr中,您可以找到子排序数组的最大长度并创建数组。
for (int i = 0;i<givenArray.size(); i++) {
int after = -1;
int length = 0;
for(int j = 0;j<i;j++) {
if (givenArray[j] < givenArray[i] && length < arr[j].maxLengthTillNow) {
length = arr[j].maxLengthTillNow;
after = j;
}
}
arr[i].maxLengthTillNow = length + 1;
arr[i].after = j;
}
复杂度:n * n
答案 1 :(得分:0)
在这里,我编写了一种方法 largestSortedSelection ,该方法将元素的向量作为输入(例如[1 2 3 10 7 8 9]),并返回布尔值向量,其中true / false表示1/0指示是否选择答案索引(例如[1 1 1 0 1 1 1 1])。
vector< bool >largestSortedSelection( vector<int>&v ){
int n = v.size();
vector< int >selectedLen(n);
vector< int >sortedList;
int maxLen = 1;
for(int i = 0; i<n; ++i){
int lb = lower_bound(sortedList.begin(),sortedList.end(),v[i])-sortedList.begin();
if( lb!=(int)sortedList.size() ){
selectedLen[i]=lb+1;
sortedList[lb]=v[i];
}
else {
sortedList.push_back(v[i]);
selectedLen[i]=(int)sortedList.size();
}
maxLen = max( maxLen, selectedLen[i] );
}
int lst = INT_MAX;//assuming maximum element will be less than INT_MAX
int len = maxLen+1;
vector< bool >selection(n,0);
for(int i = n-1; i>=0; --i ){
if( v[i]<lst && selectedLen[i]+1 == len ){
selection[i] = 1;
lst = v[i];
len--;
}
}
return selection;
}
在这种方法中:
selectedLen(i):最长到索引i的排序列表的长度。
sortedList:以递增的形式保存元素。
如果您在理解源代码时遇到困难,请告诉我。
由于我在循环中使用了N次Lower_bound函数(其复杂度为logN)。因此,总体时间复杂度为: O(N logN)。
内存复杂度将为 O(N),因为我正在使用内存来存储N个元素。
答案 2 :(得分:0)
感谢大家的帮助。这是我最后得到的Wikipedia伪代码的C ++实现:
/// Return indice of the a longest increasing subsequence.
/// implementation of https://en.wikipedia.org/wiki/Longest_increasing_subsequence
template<class T>
std::vector<size_t> indiceOfLongesIncreasingSubsequence(const std::vector<T>& v)
{
std::vector<size_t> P(v.size()), M(v.size() + 1);
size_t L = 0;
for(size_t i = 0; i < v.size(); ++i)
{
// binary search for the largest positive j <= L such that v[M[j]] < v[i]
size_t lo = 1, hi = L;
while(lo <= hi)
{
size_t mid = (lo + hi)/2;
if(v[M[mid]] < v[i])
lo = mid+1;
else
hi = mid-1;
}
// predecessor of v[i] is the last index of the subsequence of length lo-1
P[i] = M[lo-1];
M[lo] = i;
if(lo > L)
L = lo;
}
// reconstruct the longest increasing subsequence
std::vector<size_t> ind(L);
size_t k = M[L];
for(size_t i = 0; i < L; ++i)
{
ind[L-1-i] = k;
k = P[k];
}
return ind;
}
要获取真/假向量,需要:
vector<bool> selection(ind.size(), false);
for(size_t i: ind)
selection[i] = true;