1

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

4
  • (this number can be in array and can not be in array ) well I suppose you want to say (this number may be in array and may not be in array ) Commented Nov 15, 2013 at 8:45
  • qsort and then count backwards as far as you want eg. 4 in this case Commented Nov 15, 2013 at 8:46
  • it still not solved .i want to know this way (using merge sort and counter ) is good or not Commented Nov 15, 2013 at 8:52
  • Did you read this? en.wikipedia.org/wiki/Selection_algorithm Commented Nov 15, 2013 at 8:52

2 Answers 2

5

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/2th 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/2th 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/2th 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).

Sign up to request clarification or add additional context in comments.

10 Comments

+1 this is a fairly trivial algorithm to implement. The thought experiment of quicksort partitioning only into the partition holding the index of the desired element for each sub-sequence is literally spot-on.
i want to use C . can you tell a little how solve this problem ?
@storm-saeed I understand and that is what I address in the second paragraph of my answer.
@storm-saeed this question deals with specifics on how to implement the algorithm, but in essence the logic is as I explain
Sorry but I doubt your conclusion of time complexity. It is true that the average time of std::nth_element is O(n), so what about the next move? I don't get your idea that how can you use a single (or a constant number of times) call of std::nth_element to solve this problem. Please explain. Thx.
|
0

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).

Comments