1. 程式人生 > >[LeetCode] Unique Word Abbreviation 獨特的單詞縮寫

[LeetCode] Unique Word Abbreviation 獨特的單詞縮寫

An abbreviation of a word follows the form <first letter><number><last letter>. Below are some examples of word abbreviations:

a) it                      --> it    (no abbreviation)

     1
b) d|o|g                   --> d1g

              1    1  1
     1---5----0----5--8
c) i|nternationalizatio|n  --> i18n

              1
     1---5----0
d) l|ocalizatio|n          --> l10n

Assume you have a dictionary and given a word, find whether its abbreviation is unique in the dictionary. A word's abbreviation is unique if no other word from the dictionary has the same abbreviation.

Example: 

Given dictionary = [ "deer", "door", "cake", "card" ]

isUnique("dear") -> false
isUnique("cart") -> true isUnique("cane") -> false isUnique("make") -> true

這道題讓我們求獨特的單詞縮寫,但是題目中給的例子不是很清晰,我們來看下面三種情況:

1. dictionary = {"dear"},  isUnique("door") -> false

2. dictionary = {"door", "door"}, isUnique("door") -> true

3. dictionary = {"dear", "door"}, isUnique("door") -> false

從上面三個例子我們可以看出,當縮寫一致的時候,字典中的單詞均和給定單詞相同時,那麼返回true。我們需要用雜湊表來建立縮寫形式和其對應的單詞的對映,把所有縮寫形式的相同單詞放到一個set中,然後我們在判斷是否unique的時候只需要看給定單詞的縮寫形式的set裡面該單詞的個數是否和set中的元素總數相同,相同的話就是上面的第二種情況,返回true。需要注意的是由於set中不能有重複值,所有上面第二種情況只會有一個door存在set裡,但是並不影響判斷結果,參見程式碼如下:

解法一:

class ValidWordAbbr {
public:
    ValidWordAbbr(vector<string> &dictionary) {
        for (auto a : dictionary) {
            string k = a[0] + to_string(a.size() - 2) + a.back();
            m[k].insert(a);
        }
    }
    bool isUnique(string word) {
        string k = word[0] + to_string(word.size() - 2) + word.back();
        return m[k].count(word) == m[k].size();
    }
private:
    unordered_map<string, set<string>> m;
};

如果我們想省一些空間,也可以不用set,那麼我們如何區分上面的第二和第三種情況呢,我們在遇到雜湊表中沒有當前縮寫形式的時候,將該縮寫形式和當前單詞建立對映,如果該縮寫形式應經存在,那麼我們看如果對映的單詞不是當前單詞,我們將對映單詞改為空字串,這樣做的原因是,在對於第三種情況dictionary = {"dear", "door"}時,遍歷dear時,建立d2r和dear的對映,當遍歷到door的時候,由於door和dear不同,我們將對映改為d2r和“”對映,而對於第二種情況 dictionary = {"door", "door"},保留d2r和door的對映,那麼這樣在判斷door是否unique時,就可以區別第二種和第三種情況了,參見程式碼如下:

解法二:

class ValidWordAbbr {
public:
    ValidWordAbbr(vector<string> &dictionary) {
        for (auto a : dictionary) {
            string k = a[0] + to_string(a.size() - 2) + a.back();
            if (m.find(k) != m.end() && m[k] != a) m[k] = "";
            else m[k] = a;
        }
    }
    bool isUnique(string word) {
        string k = word[0] + to_string(word.size() - 2) + word.back();
        return m.find(k) == m.end() || m[k] == word;
    }
private:
    unordered_map<string, string> m;
};

參考資料: