题目: http://blog.youkuaiyun.com/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)。
本文介绍了一种在O(n)时间复杂度内寻找数组中特定元素位置的算法。该算法针对给定数组Arr[n],对每个元素Arr[i]找到满足条件Arr[k]>Arr[i]且距离最近的Arr[k]的位置。通过简洁的代码实现和正确性证明,展示了算法的有效性和高效性。
5万+

被折叠的 条评论
为什么被折叠?



