给定一个整数数组,我们如何才能得到每个元素中最接近的更大元素?例如,如果数组为A[] = {1,2,3,4,5}
,则最接近A[0] is 2
,A[1] its 3
,A[2] its 4
等等。
有没有办法比O(N^2)
有效地做到这一点?
我想到构建两个辅助阵列,其中一个将具有当前元素的所有元素并且小于它,而另一个将具有当前元素的所有元素并且大于它...但是不能继续进行......这个想法是否正确?
感谢。
答案 0 :(得分:2)
对于another question,我描述了如何为每个元素找到最左边的较大元素。这可以使用O(n)中的堆栈来完成。
您可以稍微修改算法,以便在每次迭代中都知道如何关闭右边的第一个元素。
然后你只需要应用它两次,一次使用数组,一次使用反转,然后以最小距离取出元素作为结果。
运行时:O(n)
答案 1 :(得分:0)
在O(n log n)
时间内对数组进行排序。对于输入数组中的每个元素(N
),在排序数组中进行二进制搜索(O(log n)
)。因此总复杂度为O(n log n)+O(n log n) = O(n log n)
。根据您的具体需求进行优化;例如,如果您知道输入数组以某种方式排序,那么找到相应的最接近的更大元素可能比使用二进制搜索更快。
答案 2 :(得分:0)
a)如果多次执行检索:
时间:准备的O(n * log(N)),O(log(N))用于检索;
b)如果执行单一检索:
int rc = MAXINT;
foreach x (array)
if(x > input_val && x < rc)
rc = x;
时间:O(N)
答案 3 :(得分:0)
线性时间双通算法(在Delphi中)
var
A, B: TArray<Integer>;
Stack: TStack<Integer>;
i, candidate: Integer;
begin
//source array
A := TArray<Integer>.Create(4, 2, 5, 2, 1, 6, 3, 2);
//array for positions of closest greater elements
B := TArray<Integer>.Create(-1, -1, -1, -1, -1, -1, -1, -1);
//elements that pretend to be greater
Stack := TStack<Integer>.Create;
for i := 0 to High(A) do begin
while (Stack.Count > 0) and (A[Stack.Peek] < A[i]) do
B[Stack.Pop] := i;
Stack.Push(i);
end;
//now B contains positions of greater elements to the right
// {2,2,5,5,5,-1,-1,-1}
//-1 for elements without greater right neighbour
//now walk right to left, find greater right neighbour, but use it
//if it is CLOSER than right one
for i := High(A) downto 0 do begin
while (Stack.Count > 0) and (A[Stack.Peek] < A[i]) do begin
candidate := Stack.Pop;
if (B[candidate] = -1) or (B[candidate] - candidate > candidate - i) then
B[candidate] := i;
end;
Stack.Push(i);
end;
// Result positions: {2,2,5,2,5,-1,5,6}