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

  • `(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 )` – starrify Nov 15 '13 at 08:45
  • qsort and then count backwards as far as you want eg. 4 in this case – amdixon Nov 15 '13 at 08:46
  • it still not solved .i want to know this way (using merge sort and counter ) is good or not –  Nov 15 '13 at 08:52
  • Did you read this? http://en.wikipedia.org/wiki/Selection_algorithm – Henrik Nov 15 '13 at 08:52

2 Answers2

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

Ivaylo Strandjev
  • 64,309
  • 15
  • 111
  • 164
  • +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. – WhozCraig Nov 15 '13 at 08:55
  • i want to use C . can you tell a little how solve this problem ? –  Nov 15 '13 at 08:59
  • @storm-saeed I understand and that is what I address in the second paragraph of my answer. – Ivaylo Strandjev Nov 15 '13 at 09:02
  • @storm-saeed [this question](http://stackoverflow.com/q/2392485/812912) deals with specifics on how to implement the algorithm, but in essence the logic is as I explain – Ivaylo Strandjev Nov 15 '13 at 09:04
  • for example i give 1 2 3 4 5 how solve this with your algorithm ? the answer is 2 –  Nov 15 '13 at 09:08
  • 1
    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. – starrify Nov 15 '13 at 09:10
  • My answer is wrong, because it seems I have missunderstood the question. Complexity is linear but I have to add more to my answer, I will add it right away. – Ivaylo Strandjev Nov 15 '13 at 09:16
  • @IvayloStrandjev You're not alone on the not understanding the question thing. Is the OP literally asking to supply their own pivot *value* rather than an n-th element index? If so, yeah, that would clearly be a different issue. – WhozCraig Nov 15 '13 at 09:25
  • @starrify I have edited the answer adding more details on how do we use what I propose to find the maximum `n` for which at least n elements are bigger in linear time. – Ivaylo Strandjev Nov 15 '13 at 09:26
  • @IvayloStrandjev Thank you. This time I can get your idea. :D – starrify Nov 15 '13 at 09:33
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).

Klas Lindbäck
  • 32,158
  • 4
  • 51
  • 77