给定数组Arr[n],O(n)时间内找出每个元素左侧所有元素中位置最靠近该元素且大于该元素的元素

来源:互联网 发布:2008奥运会开幕 知乎 编辑:程序博客网 时间:2024/05/18 17:01

 

题目: http://blog.csdn.net/yysdsyl/archive/2010/03/26/5419149.aspx

 

     给定数组Arr[n],对于其中的每个元素Arr[i](0=<i<n),在Arr[0...i-1]中找到元素Arr[k],Arr[k]满足Arr[k]>Arr[i],并且i-k值最小(即最靠近)。

     要求O(n)时间内找出Arr中所有元素对应的Arr[k]的位置。

     ex,

     src[]: 9, 5, 2, 4, 7

     dst[]: -1,0, 1, 1, 0

 


 

思路跟原博主一样,但要简洁点,并试图证明其正确性。

正确性证明:

line 17-23具有下面的循环不变性:

(1)Idx[i:0]维护了A[j+1:n-1]间D值尚未计算的元素的索引,且元素值是非递减的。

起始:i == -1, j + 1 == n, Idx[i:0], A[j+1:n-1]为空,平凡情况,成立。

维护:1)如果A[j] > A[Idx[i]],因此A[Idx[i]]的D值就是由A[j]得到,根据假设(1)A[Idx[i:0]]是非递减的,因此循环往前直到遇到或者某一个元素大于等于A[j],或者A[Idx[i:0]]为空,这两种情况下A[Idx[i:0]]为这次循环前的子集,且计算了D值的元素已经被删除,因此A[Idx[i:0]]满足1)的性质。这之后把A[j]加入,由于A[j] <= A[Idx[i]],且A[j]的D值没有计算,因此(1)成立。

 

         2)否则A[j] <= A[Idx[i]],又A[j]的D值没有计算,把A[j]加入,(1)仍然成立。

结束:结束时j = -1,A中所有元素考察完毕,A[Idx[i:0]]中元素D值没有计算且为非递减序的,显然其D值为-1,这由初始化获得。因此所以元素的D值都得到计算。

 

时间复杂度:算法共操作了三个n个元素的数组,A,Idx,D,A中元素仅考察一遍,时间为O(n),A的每个元素索引进入Idx最多一次,时间O(n),D最到访问两遍,时间O(n),因此总的时间O(n)。

 

 

 

 

 

 

 

原创粉丝点击