Reputation:
there is an array of numbers an this array is irregular and we should find a maximum number (n) that at least n number is bigger than it (this number may be in array and may not be in array )
for example if we give 2 5 7 6 9 number 4 is maximum number that at least 4 number (or more than it ) is bigger than 4 (5 6 7 9 are bigger)
i solve this problem but i think it gives time limit in big array of numbers so i want to resolve this problem in another way so i use merge sort for sorting that because it take nlog(n) and then i use a counter an it counts from 1 to k if we have k number more than k we count again for example we count from 1 to 4 then in 5 we don't have 5 number more than 5 so we give k-1 = 4 and this is our n .
it's good or it maybe gives time limit ? does anybody have another idea ?
thanks
Upvotes: 1
Views: 403
Reputation: 71009
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)
.
Upvotes: 5
Reputation: 33283
I would use a modified variant of a sorting algorithm that uses pivot values.
The reason is that you want to sort as few elements as possible.
So I would use qsort
as my base algorithm and let the pivot element control which partition to sort (you will only need to sort one).
Upvotes: 0