Algorithm 如何在O(n logn)时间内找到从阵列中每个位置开始的最长递增序列,

Algorithm 如何在O(n logn)时间内找到从阵列中每个位置开始的最长递增序列,,algorithm,optimization,data-structures,sequence,dynamic-programming,Algorithm,Optimization,Data Structures,Sequence,Dynamic Programming,我们如何在O(n logn)时间内找到从阵列的每个位置开始的最长递增子序列,我见过找到在阵列的每个位置结束的最长递增序列的技术,但我无法找到相反的方法 e、 g。 对于序列“3 2 4 3 2 3” 输出必须是“2 2 1”我做了一个快速而肮脏的JavaScript实现(注意:它是O(n^2)): 功能lis(a){ var tmpArr=Array(), 结果=数组(), i=a.长度; 而(我--){ var theValue=a[i], longestFound=tmpArr[theVal

我们如何在O(n logn)时间内找到从阵列的每个位置开始的最长递增子序列,我见过找到在阵列的每个位置结束的最长递增序列的技术,但我无法找到相反的方法

e、 g。 对于序列“3 2 4 3 2 3”
输出必须是“2 2 1”

我做了一个快速而肮脏的JavaScript实现(注意:它是O(n^2)):

功能lis(a){
var tmpArr=Array(),
结果=数组(),
i=a.长度;
而(我--){
var theValue=a[i],
longestFound=tmpArr[theValue]| | 1;
对于(var j=值+1;j=找到的最长时间){
longestFound=tmpArr[j]+1;
}
}
结果[i]=tmpArr[theValue]=longestFound;
}
返回结果;
}
jsFiddle:

我们从右到左遍历数组,将以前的计算保留在一个单独的临时数组中,以便后续查找

tmpArray
包含以前找到的以任何给定值开头的子序列,因此
tmpArray[n]
将表示从值
n
开始找到的最长子序列(位于当前位置的右侧)

循环是这样的:对于每个索引,我们在
tmpArray
中查找值(以及所有更高的值),以查看是否已经找到了一个子序列,该值可以在该子序列前面加上前缀。如果我们找到一个,我们只需在该长度上加1,更新
tmpArray
的值,然后移动到下一个索引。如果找不到工作(更高)的子序列,则将值的
tmpArray
设置为1,然后继续



为了使其成为O(n log n),我们观察到
tmpArray
始终是一个递减数组——它可以而且应该使用二进制搜索而不是部分循环。

编辑:我没有完全阅读文章,对不起。我认为所有序列都需要最长的递增子序列。重新编辑代码以使其正常工作

事实上,我认为在线性时间内这样做是可能的。考虑这个代码:

int a[10] = {4, 2, 6, 10, 5, 3, 7, 5, 4, 10};
int maxLength[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // array of zeros
int n = 10; // size of the array;

int b = 0;


while (b != n) {
  int e = b;     
  while (++e < n && a[b] < a[e]) {} //while the sequence is increasing, ++e
  while (b != e) { maxLength[b++] = e-b-1; }
}
inta[10]={4,2,6,10,5,3,7,5,4,10};
int maxLength[10]={0,0,0,0,0,0,0,0,0,0};//零数组
int n=10;//阵列的大小;
int b=0;
while(b!=n){
int e=b;
当(++e
第一个输出是否不是1?@leppie抱歉,它应该是子序列,因此3,4是有效的subsequence@quasiverse你能详细说明一下怎么倒过来吗?倒过来;查找在每个位置结束的LIS(可在O(n)时间内完成);反转结果。@j_random_hacker:你确定能在O(n)时间内完成吗?如果他问的是连续的子序列,那将是微不足道的,但他需要一般的LIS,如果内存可用,则为O(n logn)。这将找到线性时间内最长的递增子序列。子序列可以跳过任意数量的元素,这使得它成为一个更困难的问题。例如,
2 3 4 10
是示例序列的子序列。(是的,术语有点混乱…)
int a[10] = {4, 2, 6, 10, 5, 3, 7, 5, 4, 10};
int maxLength[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // array of zeros
int n = 10; // size of the array;

int b = 0;


while (b != n) {
  int e = b;     
  while (++e < n && a[b] < a[e]) {} //while the sequence is increasing, ++e
  while (b != e) { maxLength[b++] = e-b-1; }
}