DEV Community

Cover image for Fun With Linear Time: My Favorite Algorithm

Fun With Linear Time: My Favorite Algorithm

Andrew Healey on April 30, 2019

A Linear Time Majority Vote Algorithm I love this algorithm because it's amazing and approachable. I first saw it on a LeetCode discuss ...
Collapse
 
gmartigny profile image
Guillaume Martigny

The fact that the sequence A, A, A, B, B, C output C as the leader is a bit underwhelming.
I find the (n/2 + 1) majority limitation a little harsh, but indeed it's an elegant solution to a very common problem.

Collapse
 
healeycodes profile image
Andrew Healey

People will sometimes get stuck on that point and disregard the algorithm. I love that someone out there posted this as a puzzle which is solvable in linear time BUT has this perfect unique solution.

Collapse
 
gmartigny profile image
Guillaume Martigny

If you enjoy perfs related algo puzzles, I really liked solving this one: codingame.com/training/medium/stoc...
Overall, codingame is a great website.

Thread Thread
 
healeycodes profile image
Andrew Healey

This looks neat! Thanks for sharing.

Collapse
 
ahmedmusallam profile image
Ahmed Musallam • Edited

This is awesome!!

Could not help but rewrite it in javascript to help me understand it better. It's not the syntax, but me trying to wrap my head around it. here is what I have:

function findLeader(votes) {
  // after one vote, we have a leader
  let leader = votes[0];
  let count = 1;

  for (i = 1; i < votes.length; i++) {
    let vote = votes[i]
    if (vote === leader) // the lead may grow
      count++;
    else // or shrink
      count--; 

    // and they may be replaced
    if (count == 0) {
      leader = vote;
      count = 1;
    }
  }
  return leader;
}

console.log(findLeader(['a', 'b', 'a', 'c', 'b', 'c', 'a', 'a'])); // "a"
console.log(findLeader([0, 1, 1, 0, 1, 0, 1, 1])); // "1"

Collapse
 
healeycodes profile image
Andrew Healey

Looks great! Watch out for unshift() which could have an O(n) runtime.

Collapse
 
ahmedmusallam profile image
Ahmed Musallam

ah, good point, updated!

Collapse
 
xngwng profile image
Xing Wang

The leader election algorithms, who knew that have computers making seemingly simple decisions in a distributed setting could be so hard and fascinating.

en.wikipedia.org/wiki/Leader_election

Collapse
 
healeycodes profile image
Andrew Healey • Edited

Wow! Really fascinating stuff. I’m interested in some of the code behind this.

Collapse
 
subsr97 profile image
Subramanian 😎

Took me quite some time to comprehend. Good one though!

But I have a couple genuine questions.

Is this algorithm practically applicable? If we needed to implement a voting system, would we use this algorithm?

And, will this behavior reflect in real life where we have huge number of elements?

The fact that the sequence A, A, A, B, B, C output C as the leader is a bit underwhelming.
I find the (n/2 + 1) majority limitation a little harsh, but indeed it's an elegant solution to a very common problem.

Collapse
 
healeycodes profile image
Andrew Healey

It seems pretty rare that you'd have a large data set and know that there is a majority without knowing what that majority is. But if that was the case, then this would be the optimal algorithm.

It was more important when older computers had different restrictions:

Note that the algorithm fetches the elements of A in linear order. Thus, the algorithm can be used efficiently when the number of votes is so large that they must be read from magnetic tape.

Collapse
 
tasmacncheese profile image
Aditya

Your naive solution needs a bit of updating. You never update the max_votes and as such such will only remain 0. Should be

if candidates[i] > max_votes:
    leader = i
    max_votes = candidates[i]
Collapse
 
healeycodes profile image
Andrew Healey

You’re correct! I must have typoed when I copied it over. Thanks, updated.

Collapse
 
val_baca profile image
Valentin Baca

Your code is missing an important element:

"Even when the input sequence has no majority, the algorithm will report one of the sequence elements as its result....This second pass is needed, as it is not possible for a sublinear-space algorithm to determine whether there exists a majority element in a single pass through the input."

Otherwise, [A, B, C] => C

Collapse
 
healeycodes profile image
Andrew Healey

Hi Valentin, a majority element cannot be confirmed with one-pass but if there is a majority element (as per the problem statement) it will be found 🔍