8

I want to discuss an algorithm here which I found in a data structure book. This book presents a sketch of the algorithm to find the majority element (appears more than N/2 ) in an array of size N . The sketch of the algorithm is as follows:

First, a candidate majority element is found ( this is the harder part ). This candidate is the only element that could possibly be the majority element.The second step determines if this candidate is actually the majority. This is just a sequential search through the array. To find a candidate in the array, A, form a second array B. Then compare A1,A2. If they are equal, add one of these to B; otherwise do nothing. Then compare A3 and A4. Again if they are equal, add one of these to B; otherwise do nothing. Continue in this fashion until the entire array is read. Then recursively find a candidate for B; this is the candidate for A.

I figured out if the N is even, algorithm works fine. But what if N is odd ? How we can handle this case?

Rajeev
  • 203
  • 2
  • 10
  • Is the array ordered? – ChiefTwoPencils Jun 30 '13 at 08:59
  • note: there is a better alorithm, which check every element only once. – Karoly Horvath Jun 30 '13 at 09:03
  • I think you should read about Divide and conquer technique – banarun Jun 30 '13 at 09:11
  • 1
    I don't see a way to extend this algorithm to arrays which aren't a power of 2 in size. Whether you add the last element in an odd array to B or not, you can find a counterexample where this will give the wrong result. A better way to find the candidate element is the [Boyer-Moore voting algorithm](http://www.cs.utexas.edu/~moore/best-ideas/mjrty/) which will do it in one pass with O(1) space. – interjay Jun 30 '13 at 09:15
  • @C.Lang The array is not sorted – Rajeev Jun 30 '13 at 09:29
  • @KarolyHorvath You are right. There are other better algorithms, but I was just wondering how this algorithm would handle the case when N is odd – Rajeev Jun 30 '13 at 09:30
  • 5
    @C.Lang If the array was ordered, finding the candidate would be O(1) since a majority element is always the median. – Imre Kerr Jun 30 '13 at 09:34
  • See also http://stackoverflow.com/questions/780937 – Matthew Strawbridge Jun 30 '13 at 09:35
  • @interjay even I am not able to figure out how this would be handled. For example in sequence 121212121, how last digit 1 would be handled ? As in array B, there wont be any element. – Rajeev Jun 30 '13 at 09:36
  • Off the top of my head: add the odd element but mark it as deficient. When combining a regular element with a deficient one, the result is deficient. When you are left with two elements and one is deficient, take the other one. Only the last element of the array may be deficient so you only need one extra bit. – n. m. could be an AI Jun 30 '13 at 09:57

5 Answers5

4

Majority Element:

A majority element in an array A[] of size n is an element that appears more than n/2 times (and hence there is at most one such element).

Finding a Candidate:

The algorithm for first phase that works in O(n) is known as Moore’s Voting Algorithm. Basic idea of the algorithm is if we cancel out each occurrence of an element e with all the other elements that are different from e then e will exist till end if it is a majority element.

findCandidate(a[], size)
1.  Initialize index and count of majority element
     maj_index = 0, count = 1
2.  Loop for i = 1 to size – 1
    (a)If a[maj_index] == a[i]
        count++
    (b)Else
        count--;
    (c)If count == 0
        maj_index = i;
        count = 1
3.  Return a[maj_index]

Above algorithm loops through each element and maintains a count of a[maj_index], If next element is same then increments the count, if next element is not same then decrements the count, and if the count reaches 0 then changes the maj_index to the current element and sets count to 1. First Phase algorithm gives us a candidate element. In second phase we need to check if the candidate is really a majority element.

Second phase is simple and can be easily done in O(n). We just need to check if count of the candidate element is greater than n/2.

Aditya
  • 5,509
  • 4
  • 31
  • 51
  • 2
    The answer is from [geeksforgeeks](http://www.geeksforgeeks.org/majority-element/) – Aditya Jul 01 '13 at 05:46
  • I am sorry adi but this is not the answer of my question. I need to know how to handle the odd case in the algorithm mentioned in my question. – Rajeev Jul 01 '13 at 05:54
  • 1
    Can you give the source of where you found the algorithm – Aditya Jul 01 '13 at 05:58
1

A majority element in an array A[] of size n is an element that appears more than n/2 times

 int find(int[] arr, int size) { 
  int count = 0, i, mElement;
 for (i = 0; i < size; i++) {
    if (count == 0)
        mElement = arr[i];
    if (arr[i] == mElement) 
        count++;
    else
        count--;
  }
 count = 0;
 for (i = 0; i < size; i++)
    if (arr[i] == mElement)
         count++;
  if (count > size/2)
        return mElement;
  return -1;
 }
coder101
  • 840
  • 2
  • 11
  • 29
0

Algorithm that you have explained works on the following idea:

  1. If two successive elements are equal, then that is the potential majority element and include it in the result set (for further processing)

  2. If two elements are distinct, then this particular pair does not decide the winner.

Point #2 is crucial - suppose that (A1, A2) pair contains the majority element (A1) and another minority element (A2). Remove this pair. A1 remains majority in the remainder of the array.

If you have understood this explanation, then you understand why nothing is added to B when elements differ.

Corrolary to the algorithm, regarding an array containing odd number of elements, would then be: add an odd element to B. Reason is the same as #1: it might be the majority element, and it should be included in the output just to be sure that its count is not lost in the process.

Anyway, the whole thing can be done without the other array B. Here you can find much simpler algorithm: Finding a Majority Element in an Array

Zoran Horvat
  • 10,924
  • 3
  • 31
  • 43
0

Here are three algorithms that solve the problem:

1) Scan the elements of the array, accumulating a frequency of each distinct element using some sort of dictionary (hash table, balanced tree). When the scan is complete, pick the only dictionary item with a count greater than n/2, or report that no element has a majority.

2) The majority element must be the median of the array if it exists. Compute the median using the median-of-five technique or any other algorithm, and confirm that it is greater than n/2.

3) An algorithm of Boyer and Moore (the same guys that did the string-matching algorithm) picks the first array element as the candidate item and assigns a count of 1, then scans the array, adding 1 to the count if the next item is the same as the current candidate, subtracts 1 from the count if the next item differs from the current candidate, and resets the candidate to the next array element, with a count of 1, whenever the count reaches 0. At the end of the scan the current candidate is a member of the majority if a majority exists, so a second scan is required to confirm that the candidate does form a majority.

I discuss and implement all three algorithms at my blog.

user448810
  • 17,381
  • 4
  • 34
  • 59
-1

I think your algorithm won't work when N is even too. I can prove it with an example:

Consider array of 8 elements say 2,2,1,1,3,2,2,2. Now your B array will be 2,1,2 as per you statement. If you repeat the above step again. There won't be any candidates. But the actual answer here is '2'. So this method is definitely wrong.

This problem was discussed on Geeks for geeks. I think this will help you:

http://www.geeksforgeeks.org/majority-element/

banarun
  • 2,305
  • 2
  • 23
  • 40
  • 4
    This doesn't answer the question regarding the given algorithm. And it's entirely copy-pasted from a website. – interjay Jun 30 '13 at 09:26
  • @banarun This does not answer my question. – Rajeev Jun 30 '13 at 09:33
  • @interjay Sorry, I removed that content. – banarun Jun 30 '13 at 13:42
  • In your example, the B array has odd length, so you can't apply the algorithm recursively unless you define what needs to happen in that case (which is what the question asks). – interjay Jun 30 '13 at 13:49
  • That's what I'm saying. We can never know whether B will be even or odd. So we can't apply this algorithm in the first place. – banarun Jun 30 '13 at 13:52
  • But that's exactly what the question is - how do we extend this algorithm to be able to apply it to all cases? That there are cases it doesn't handle is already known. – interjay Jun 30 '13 at 13:53
  • What I am saying is, we cannot (as far as I know) – banarun Jun 30 '13 at 13:54
  • That's not what your answer says, it just gives an example for something we already knew. Besides, how do you know we cannot extend it? For example, n.m.'s comment above seems like a good attempt. – interjay Jun 30 '13 at 14:01
  • If B is odd every time, we get O(log n) deficient elements. My point is there is an O(n) running time and O(1) space algorithm. It would be much useful. – banarun Jun 30 '13 at 14:11
  • I know that there is a better algorithm, which is why I already mentioned it in a comment above (where it belongs, rather than in an answer) even before you posted your answer. And in n.m.'s solution there can only be a single deficient element in each array (I don't know if always gives the correct result though). – interjay Jun 30 '13 at 14:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/32640/discussion-between-banarun-and-interjay) – banarun Jun 30 '13 at 14:23