In c++
there is a function called std::nth_element
and it can find the nth element of an array in linear time. Using this function you should find the N - n
- th element (where N
is the total number of elements in the array) and subtract 1 from it.
As you seek a solution in C
you can not make use of this function, but you can implement your solution similarly. nth_element
performs something quite similar to qsort, but it only performs partition on the part of the array where the n-th element is.
Now let's assume you have nth_element
implemented. We will perform something like combination of binary search and nth_element
. First we assume that the answer of the question is the middle element of the array (i.e. the N/2-th element). We use nth_element
and we find the N/2
th element. If it is more than N/2
we know the answer to your problem is at least N/2
, otherwise it will be less. Either way in order to find the answer we will only continue with one of the two partitions created by the N/2
th element. If this partition is the right one(elements bigger than N/2
) we continue solving the same problem, otherwise we start searching for the max element M
on the left of the N/2
th element that has at least x
bigger elements such that x + N/2 > M
. The two subproblems will have the same complexity. You continue performing this operation until the interval you are interested in is of length 1
.
Now let's prove the complexity of the above algorithm is linear. First nth_element
is linear performing operations in the order of N
, second nth_element
that only considers one half of the array will perform operations in the order of N/2
the third - in the order of N/4
and so on. All in all you will perform operations in the order of N + N/2 + N/4 + ... + 1
. This sum is less than 2 * N
thus your complexity is still linear.
Your solution is asymptotically slower than what I propose above as it has a complexity O(n*log(n))
, while my solution has complexity of O(n)
.