Actually, if you go into fully pedantic mode, the set version is worse. Hash-based set insertion is commonly taken to be O(1), but that depends on hash comparison being O(1), which depends on using single-word hash values, which means your n is bounded by eg 2^63 (50% occupancy) or whatever. Honestly fine in practice, but hash lookup isn't "as" O(1) as indexing into an array. (ie, it requires a less realistic cost model.)
You also need your keys' length to be bounded by a constant. Otherwise just hashing everything will exceed O(n).
In reality random indexing is O(sqrt(n)) for 2D memory chips, and at best O(cbrt(n)) in our 3D physical world.
let mut hash_set = HashSet::new();
let mut len = 0;
for i in 0..arr.len() {
if !hash_set.contains(&arr[i]) {
hash_set.insert(arr[i]);
arr[len] = arr[i];
len += 1;
}
}
arr.truncate(len);You can also use radix sort for what I'd like to call "fake" O(n) sort since physical hardware puts an upper limit on the hidden constant.
> The “aha” moment here comes if you realize that by sorting the input, you can just walk along the array with all duplicates being next to each other, resulting in an efficient solution.
You could also stick all the numbers in a set, since it seems like order doesn't matter…