11

Given an array , for every element I need to find the smallest element to the right of the given element which is greater than the current element.

Mathematically, For every index i in array A, I need to find index j such that

A[j] > A[i]
j > i
A[j] - A[i] is minimum

I need to find j for every index i

The brute force solution would be O(n^2) and I am hoping to do better. I am thinking that an O(n log n) solution is possible using self-balancing BST but that seems pretty complex. Moreover I need a O(n) solution.

Is there a O(n) solution to this problem? Is there a proof that the lower bound is O(n log n)?

Codor
  • 17,447
  • 9
  • 29
  • 56
Sam Radhakrishnan
  • 681
  • 1
  • 5
  • 19

1 Answers1

9

Proof of O(nlogn) lower bound: (for comparison based algorithms)

Lets say we have a comparison-based algorithm that would accomplish this task in O(n). That is for each index, we have the immediate greater element to its right (say R[i]).

Similarly we can run this algorithm on the reversed input array and then reverse the result. For each index we have the immediate greater element to its left (say L[i]).

This means that in O(n) we have for each element, the immediate greater element in the array = min (R[i], L[i]).

We can now sort the array using this information.

Find the minimum element in the array. Find its successor (immediate greater element), then its successor's successor etc. Hence you would have got the entire array in sorted order.

Sorted the array in O(n) using only comparisons (a contradiction).

O(nlogn) Algorithm:
Start building the balanced BST from the right of the array. The nodes would contain the values and the respective indices.

Then for each new element encountered, inserting it in the BST would get corresponding nearest larger index/value.

Abhishek Bansal
  • 12,589
  • 4
  • 31
  • 46
  • We can not completely sort on the basis of exactly how you described. We have just larger element on its right, not overall. Can you please clarify? – Akashdeep Saluja Jul 12 '16 at 06:26
  • 1
    @AkashdeepSaluja We find the immediate larger element to its right (say R[i]). Similarly we can find the immediate larger element to its left (say L[i]) by running this algorithm in reverse. This means that have immediate larger element = min (R[i], L[i]). – Abhishek Bansal Jul 12 '16 at 06:30
  • One could also obtain on `O(n log n)` algorithm by creating a type containing the value and the index in the original array and sorting these for the value. – Codor Jul 12 '16 at 06:50
  • @Codor, we want immediate greater element 'to the right'. After sorting, how can we determine for each element the immediate greater element to its right in total O(n) time? – Abhishek Bansal Jul 12 '16 at 06:53
  • Your proof of lowerbound holds **only** if our algorithm is comparison based. We could probably come up with something like counting sorts and obtain an O(n+k) solution where `k` depends on the maximum value in the array. – Bakuriu Jul 12 '16 at 11:00
  • @Bakuriu If we have to find the element just 'greater' than the index element then it is bound to be comparison based. – Abhishek Bansal Jul 12 '16 at 11:01
  • @AbhishekBansal No, it's not. I'm not saying that it's trivial to find such an algorithm, but that I'm quite sure such an algorithm might exist. If you think this is not the case you should add a proof to your answer that no algorithm that doesn't contain comparisons between elements of the arrays can be correct... good luck providing such proof. – Bakuriu Jul 12 '16 at 11:07
  • @Bakuriu Ok, I see your point. Will mention the assumption in the answer. Thanks – Abhishek Bansal Jul 12 '16 at 11:22