Cracking the code interviews – Solution
Chapter 1 Arrays & Strings
1.1 Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structure?
If the characters comes from the ASCII table, there can only be 256 types of them. We can use a boolean array of size 256 to mark each type of characters. This is the same idea of Bucket-sort algorithm.
About Bucket-Sort: http://en.wikipedia.org/wiki/Bucket_sort
When a new character is already marked as true (already appeared), then we will know that this string contains duplicate characters. The time complexity of isUnique() is O(n) and space complexity is O(1).
Here is my solution in c++:
bool
isUnique(string str)
{
// if length bigger than 256, it must have duplicate character
if(str.size() >= 256) return false;
// use idea of Bucket-sort to find the duplicate character
bool bucket[256] = {}; // remember every ASCII character
for(size_t i=0; i<str.size(); ++i)
{
// mark the appeared character to true
// if already set true, report the duplicated character
if(bucket[str[i]])
return false;
bucket[str[i]] = true;
}
return true;
}
Another solution is to use a 256-bit-map to mark the characters in ASCII table.
The time / space complexity of isUniqueV2() is also O(n) / O(1).
bool
isUniqueV2(string str)
{
// if length bigger than 256, it must have duplicate character
if(str.size() >= 256) return false;
// use idea of Bucket-sort to find the duplicate character
uint64_t bucket[4] = {};
for(size_t i=0; i<str.size(); ++i)
{
int index = str[i] / 64; // which bucket should be check
int bit = str[i] % 64; // which bit in the bucket should be check
// mark the appeared character to true
// if already set true, report the duplicated character
if( (bucket[index] & (1 << bit)) != 0)
return false;
bucket[index] |= (1 << bit);
}
return true;
}