【LintCode 题解】819. 【中等】单词排序

  • 难度:中等
  • Facebook 面试题

题目

给一个新的字母表,如 {c, b, a, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z},根据新的字母表排序字符串数组。

注意事项

  • 输入的单词长度不超过 100。
  • 输入的单词总数不超过 10000。
  • 可以认为,输入的新字母表即一个长度为 26 的字符串。
  • 保证题目只会出现小写字母。

样例

Sample Input:
"cbadefghijklmnopqrstuvwxyz"
["cab", "cba", "abc"]

Sample Output:
["cba", "cab", "abc"]
Sample Input:
"zbadefghijklmnopqrstuvwxyc"
["bca", "czb", "za", "zba", "ade"]

Sample Output:
["zba", "za", "bca", "ade", "czb"]

解答

这题理论上可以使用 std::sort 实现,这样就只需要编写一个比较函数即可。

不过这题似乎不能这么写,于是只能手写排序算法了

判断字母在新字母表的位置可以用自带的 find() 实现,代码如下。

class Solution 
{
private:
    string newAlphabet;

    bool lessThan(const string &a, const string &b) 
    {
        auto p = a.begin(), q = b.begin();
        while(p != a.end() && q != b.end()) 
        {
            size_t posP = newAlphabet.find(*p), posQ = newAlphabet.find(*q);
            if(posP == posQ) 
            {
                ++p, ++q;
                continue;
            }
            else if(posP < posQ)
                return true;
            else
                return false;
        }
        if(p == a.end())
            return true;
        else
            return false;
    }

    void insertionSort(vector &words, size_t left, size_t right) 
    {
        string temp;
        size_t p, j;
        for(p = left; p < right; p++) 
        {
            temp = words[p];
            for(j = p; j != 0 && lessThan(temp, words[j - 1]); j--)
                swap(words[j], words[j - 1]);
            words[j] = temp;
        }
    }

    void merge(vector &words, size_t left, size_t mid, size_t right) 
    {
        vector temp(right - left + 1);
        size_t p = left, q = mid, i = 0;
        while(p != mid && q != right) 
        {
            if(lessThan(words[p], words[q])) {
                temp[i++] = words[p];
                p++;
            }
            else 
            {
                temp[i++] = words[q];
                q++;
            }
        }
        while(p != mid)
            temp[i++] = words[p++];
        while(q != right)
            temp[i++] = words[q++];

        for(size_t j = 0; j < i; j++)
            words[left + j] = temp[j];
    }

    void mergeSort(vector &words, size_t left, size_t right) 
    {
        if(right - left <= 10) 
        {
            insertionSort(words, left, right);
            return;
        }
        size_t mid = left + (right - left) / 2;
        mergeSort(words, left, mid);
        mergeSort(words, mid, right);
        merge(words, left, mid, right);
    }
public:
    /**
     * @param alphabet: the new alphabet
     * @param words: the original string array
     * @return : the string array after sorting
     */
    vector wordSort(string &alphabet, vector &words) {
        if(words.size() < 2)
            return words;
        newAlphabet = alphabet;
        mergeSort(words, 0, words.size());
        return words;
    }
};

你可能感兴趣的:(【LintCode 题解】819. 【中等】单词排序)