Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An interesting Google interview algorithm I found online that requires linear time [closed]

So I found this Google interview algorithm question online. It's really interesting and I still have not come up with a good solution yet. Please have a look, and give me a hint/solution, it would be great if you can write the code in Java :).

"Design an algorithm that, given a list of n elements in an array, finds all the elements that appear more than n/3 times in the list. The algorithm should run in linear time. (n >=0 ) You are expected to use comparisons and achieve linear time. No hashing/excessive space/ and don't use standard linear time deterministic selection algo"

like image 421
Newbie_code Avatar asked Dec 02 '11 20:12

Newbie_code


2 Answers

My solution was inspired by the Tetris game. Solution highlight (dubbed as 'Tetrise process'): use three key-value pairs for bookkeeping, with key the element, value the count of the element. In a main loop, we keep at most 3 latest distinct elements. When the count of all three keys are non-zero, we decrement the counts of all and eliminate zero-count key(s), if any. At the end, there may or may not be some residual elements. These are the survivors of the Tetris process. Note that there can be no more than 3 residual elements. If nothing left, we return null. Otherwise we loop through the original n elements, counting the number of these residual elements and return those whose count is > n/3.

Hint of proof: To show the correctness of the above algorithm, note that for an element must survive the Tetris process or remain in the residue to satisfy the requirement. To see why, let's denote the number of removal operations as m and the total count of residual elements r. Then we have n = 3 * m + r. From here we get m <= n/3, because r >= 0. If an element didn't survive the Tetrise process, the maximum occurrence it can appear is m <= n/3.

Time complexity O(n), space complexity O(1).

like image 107
Chivalryman Avatar answered Nov 17 '22 16:11

Chivalryman


Hint: Look at Boyer and Moore's Linear Time Voting Algorithm

Better Hint: Think about solving the majority problem first. That is, try to find an element that occurs at least n/2 times. The 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 until the end if it is a majority element.

findCandidate(a[], size)
    //Initialize index and count of majority element
    maj_index = 0;
    count = 1;

    for i = 1 to n–1 {
      if a[maj_index] == a[i]
          count++;
      else
          count--;

      if count == 0 {
          maj_index = i;
          count = 1;
      }
    }
    return a[maj_index]

This algorithm loops through each element and maintains a count of a[maj_index]. If the 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.

Next you need to check that this element indeed occurs at least n/2 times, but that can be done in one pass.

like image 7
PengOne Avatar answered Nov 17 '22 17:11

PengOne