找到最接近的更大元素的每个元素

时间:2014-03-20 18:28:49

标签: algorithm sorting

给定一个整数数组,我们如何才能得到每个元素中最接近的更大元素?例如,如果数组为A[] = {1,2,3,4,5},则最接近A[0] is 2A[1] its 3A[2] its 4等等。 有没有办法比O(N^2)有效地做到这一点? 我想到构建两个辅助阵列,其中一个将具有当前元素的所有元素并且小于它,而另一个将具有当前元素的所有元素并且大于它...但是不能继续进行......这个想法是否正确? 感谢。

4 个答案:

答案 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)如果多次执行检索:

  1. 对数组进行排序:O(n * log(N));将UNDEF添加到数组的右端
  2. 找到i:元素的位置O(log(N))
  3. return arr [i + 1];
  4. 时间:准备的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}