Reputation: 33
I'm practicing the cracking the code interview on my spare time. The question states: Is Unique: Implement an algorithm to determine if a string has all unique character. What if you cannot use additional data structures?
The solution I found is: https://github.com/careercup/CtCI-6th-Edition-cpp/blob/master/Ch%201.Arrays%20And%20Strings/1.Is%20Unique/1.%20Is_unique.cpp
My implementation is:
bool UniqueCharsHash(string word) {
map<char, bool> uniqueChar; //keyType, valueType
for (int i = 0; i < word.length(); i++) {
char letter = tolower(word[i]);
if (!uniqueChar[letter]) {
uniqueChar[letter] = true;
} else {
return false;
}
}
return true;
}
//O(n^2) run time using a two loops (1 outer and 1 inner)
bool UniqueCharNoDS(string word) {
for (int i = 0; i < word.length() - 1; i++) {
for (int j = i + 1; j < word.length(); j++) {
if (word[i] == word[j]) {
return false;
}
}
}
return true;
}
but in the hint portion of the book it states:
I was wondering in the 3 methods shown, are any of those NlogN time?
Upvotes: 0
Views: 737
Reputation: 105
An O(n) time could be used with the hint (#2) provided. Where you shift bits and flip if a letter has already been seen.
static boolean isUniqueNoStruct(String input) {
// Length check
if (input.length() > 256)
return false;
// Assuming only lowercase 32 bit characters
int checkVal = 0;
for (int i = 0; i < input.length(); i++) {
int bit = input.charAt(i) - 'a';
// If the bit at the index has been flipped return false
if ((checkVal & ( 1 << bit)) > 0) {
return false;
}
checkVal |= (1 << bit);
}
return true;
}
Upvotes: 0
Reputation: 792
This code solves it in O(NlogN) time, it is a modification of merge sort
boolean isUnique(char[] arr){
return sort(arr,0,arr.length-1);
}
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
boolean merge(char arr[], int l, int m, int r)
{
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
/* Create temp arrays */
char L[] = new char [n1];
char R[] = new char [n2];
/*Copy data to temp arrays*/
for (int i=0; i<n1; ++i)
L[i] = arr[l + i];
for (int j=0; j<n2; ++j)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays */
// Initial indexes of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarry array
int k = l;
while (i < n1 && j < n2)
{
if (L[i] < R[j])
{
arr[k] = L[i];
i++;
}
else if(L[i] > R[j])
{
arr[k] = R[j];
j++;
}
else{
return false;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy remaining elements of L[] if any */
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
return true;
}
// Main function that sorts arr[l..r] using
// merge()
boolean sort(char arr[], int l, int r)
{
if (l < r)
{
// Find the middle point
int m = (l+r)/2;
// Sort first and second halves
boolean left= sort(arr, l, m);
boolean right = sort(arr , m+1, r);
// Merge the sorted halves
return left&&right&&merge(arr, l, m, r);
}
return true;
}
Upvotes: 0
Reputation: 1
The below code (in Java) will determine if a string has all unique character.
Time complexity --> O(n)
final static int LETTERS_LEN = 256;
public static boolean isUnique(String str){
int[] letters = new int[LETTERS_LEN];
for (int i = 0; i < str.length(); i++) {
letters[str.charAt(i)]++;
}
for (int i = 0; i < LETTERS_LEN; i++) {
if (letters[i] > 1) {
return false;
}
}
return true;
}
Upvotes: 0
Reputation: 241901
As has often been pointed out, this question is solvable in O(1) because the longest string made up of unique characters is 256 characters long.
So when/if your algorithm hits the 257th character, it can stop and report "no".
Even if you use the naive algorithm of searching each character in the prefix up to that point, there are a maximum of 255*128 comparisons before the limit is reached. (No adjustment to the algorithm is necessary; it must report "no" on the 257th character if there is one.)
Upvotes: 1