Got a phone interview recently. The question is how to find out an integer which appears more than 50% times in an array of integers. For example, [1 1 0 1 2] should return 1, while [1 1 0 2 3] should return nothing.
Solution
The basic idea is finding out a candidate before checking if it repeats more than enough times. The algorithm is described in a paper entitled "Finding Repeated Elements" by Misra and Gries. The algorithm consists of two steps. First, it identifies a candidate value. The candidate value either occurs >50% of the time or there is no element in the array that occurs >50% of the time. The second step verifies whether the candidate element does indeed occur >50% of the time. Here's the algorithm, implemented in C:
#define undefined (-1) int find_element(int array[], int n) { /* Step 1: Find the element that occurs >50% of the time, if there is one. */ int c = 0; int candidate = undefined; for (int i = 0; i < n; i ++) { if (array[i] == candidate) /* Match. */ c += 2; else if (i == c) /* New candidate. */ { c += 2; candidate = array[i]; } } /* Step 2: Verify that the candidate actually occurs >50% of the time. */ for (i = 0, c = 0; i < n; i ++) if (array[i] == candidate) c ++; if (c * 2 > n) return candidate; else return undefined; }
No comments:
Post a Comment