The pigeonhole argument for 'at most two' came to me pretty fast, that part felt good.
Start by proving the at-most-two property using a counting argument, then use binary search to find the first and last occurrence of each candidate value (the elements at indices n/3 and 2n/3). Verify their counts exceed n/3, and handle edge cases like empty arrays and all-equal elements.
Pro tip: Mention that the O(log n) time bound is tight because any correct algorithm must at least read the candidate elements, and explicitly discuss how you'd handle the case where the array length is not a multiple of 3.
Use a counting argument: if three distinct values each appeared more than n/3 times, their total count would exceed n, which is impossible. Thus, at most two such values exist.
In a sorted array, any value appearing more than n/3 times must include either the element at index floor(n/3) or the element at index floor(2n/3) (or both). Use these indices to pick at most two candidate values.
For each candidate, use binary search to find its first and last occurrence, compute its frequency, and check if it exceeds n/3. This takes O(log n) time per candidate.
If the array is empty, return an empty list. If all elements are equal, the candidate will be that element and its count will be n, which exceeds n/3. Also handle small arrays (n < 3) where the condition may be trivially satisfied.
The algorithm uses O(1) extra space and O(log n) time (constant number of binary searches). Correctness follows from the candidate property and the verification step.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.