I want to filter efficiently a list of integers for duplicates in a way that only the resulting set needs to be stored.
One way this can be seen:
- we have a range of integers $S = \{1, \dots{}, N\}$ with $N$ big (say $2^{40}$)
- we have a function $f : S \to S$ with, supposedly, many collisions (the images are uniformly distributed in $S$)
- we then need to store $f[S]$, that is $\{f(x) | x \in S\}$
I have a quite accurate (probabilistic) estimation of what $|f[S]|$ is, and can therefore allocate data structures in advance (say $|f[S]| \approx 2^{30}$).
I have had a few ideas, but I am not sure what would be the best approach:
- a bitset is out of the question because the input set does not fit into memory.
- a hash table, but (1) it requires some memory overhead, say 150% of $|f[S]|$ and (2) the table has to be explored when built which requires additional time because of the memory overhead.
- an "on the fly" sort, preferably with $O(N)$ complexity (non-comparison sort). Regarding that, I am not sure what is the major difference between bucket sort and flashsort.
- a simple array with a binary search tree, but this requires $O(N \log |f[S]|)$ time.
- maybe using Bloom filters or a similar data structure could be useful in a relaxation (with false positives) of the problem.
Some questions on stackoverflow seem to tackle with this sort of things (http://stackoverflow.com/questions/12240997/sorting-array-in-on-run-time, http://stackoverflow.com/questions/3951547/java-array-finding-duplicates), but none seems to match my requirements.