The original post is here: Thoughts inspired by a Tencent algorithm problem. Since there was no place to leave him a comment about this solution, I’ll just dash off a blog post.
The Problem
The problem is roughly:
There are currently ten thousand and one numbers (unordered), in the range 1~10000. Except for two duplicated numbers, all other numbers are unique. How to find these two duplicate numbers fastest?
A simple analysis: 1~10000 is 10000 numbers in total, so the one extra number is the duplicated number we’re looking for.
Take the array below as an example; the final 23 is what we want.
1 | [1, 2, 3, 4, ..., 10000, 23] |
Of course the example above is simple — the answer is visible at a glance; a shuffled array is not so easy to see through.
How to Solve It
A shuffled array is indeed hard to judge, so let’s still look at this special ordered form.
Please try marking the array indices, into a table like this:
| array value | 1 | 2 | 3 | 4 | 5 | ….. | 10000 | 23 |
| array index | 0 | 1 | 2 | 3 | 4 | …. | 9999 | 10000 |
Have you noticed — merging the array indices with the original array values, what does it look like?
1 | 0, 1, 1, 2, 2, 3, 3, 4, 4 ... 10000, 10000, 23 |
The problem then transforms into: in 1~10000, all numbers appear twice (excluding 0), one number appears three times, and we need to find this number — just bring out our XOR method.
The array above is in order; even a shuffled array can always be rearranged to obtain this relationship.
Below is my solution, written directly in Python for convenience:
1 | import random |
Time and Space Complexity Analysis
Since the problem specifies 10001 numbers, the time complexity works out to O(10000), and the space complexity is O(1).
Not being able to leave a comment is really annoying — I hope everyone’s blogs can add a message board too, for the sake of communication.