数组和字符串破解代码访谈第6版Soln 1.1

时间:2017-04-15 17:57:08

标签: arrays string algorithm c++11 data-structures

我正在练习在业余时间破解代码面试。 问题陈述:是唯一的:实现一种算法来确定字符串是否具有所有唯一字符。如果您不能使用其他数据结构怎么办?

我找到的解决方案是:https://github.com/careercup/CtCI-6th-Edition-cpp/blob/master/Ch%201.Arrays%20And%20Strings/1.Is%20Unique/1.%20Is_unique.cpp

我的实施是:

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;
}

但在本书的暗示部分中指出:

  1. 尝试哈希表
  2. 有点矢量有用
  3. 你可以在O(Nlogn)时间内解决它吗
  4. 我想知道在显示的3种方法中,是否有任何NlogN时间?

4 个答案:

答案 0 :(得分:1)

正如经常指出的那样,这个问题在O(1)中是可解的,因为由唯一字符组成的最长字符串长度为256个字符。

因此,当你的算法击中第257个字符时,它可以停止并报告&#34; no&#34;。

即使你使用天真算法搜索前缀中的每个字符直到该点,在达到限制之前最多有255 * 128个比较。 (不需要对算法进行调整;如果有的话,必须在第257个字符上报告&#34; no&#34 ;.

答案 1 :(得分:0)

以下代码(在Java中)将确定字符串是否具有所有唯一字符。
时间复杂度 - &gt;为O(n)

ipython

答案 2 :(得分:0)

此代码在O(NlogN)时间内解决它,它是合并排序的修改

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;
}

答案 3 :(得分:0)

O(n)时间可以与提供的提示(#2)一起使用。如果已经看到一个字母,则在其中移位并翻转。

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;
}