1. 程式人生 > >[LeetCode] Generalized Abbreviation 通用簡寫

[LeetCode] Generalized Abbreviation 通用簡寫

Write a function to generate the generalized abbreviations of a word.

Example:

Given word = "word", return the following list (order does not matter):

["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]

這道題讓我們對一個單詞進行部分簡寫,簡寫的規則是若干個字母可以用數字來表示,但是不能有兩個相鄰的數字,具體可以參考題目中給的例子,根據我以往的經驗,這種列舉所有情況的必定是要用DFS來寫的,但是我一時半會又沒想到該咋遞迴,後來我數了一下題目中給的例子的所有情況的個數,是16個,而word有4個字母,剛好是2的4次方,這是巧合嗎,當然不是,後來我又發現如果把0到15的二進位制寫出來,每一個可以對應一種情況,如下所示:

0000 word
0001 wor1
0010 wo1d
0011 wo2
0100 w1rd
0101 w1r1
0110 w2d
0111 w3
1000 1ord
1001 1or1
1010 1o1d
1011 1o2
1100 2rd
1101 2r1
1110 3d
1111 4

那麼我們就可以觀察出規律,凡是0的地方都是原來的字母,單獨的1還是1,如果是若干個1連在一起的話,就要求出1的個數,用這個數字來替換對應的字母,既然規律找出來了,那麼程式碼就很好寫了,如下所示:

解法一:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector
<string> res; for (int i = 0; i < pow(2, word.size()); ++i) { string out = ""; int cnt = 0, t = i; for (int j = 0; j < word.size(); ++j) { if (t & 1 == 1) { ++cnt; if (j == word.size() - 1
) out += to_string(cnt); } else { if (cnt != 0) { out += to_string(cnt); cnt = 0; } out += word[j]; } t >>= 1; } res.push_back(out); } return res; } };

上述方法返回結果的順序為:

["word","1ord","w1rd","2rd","wo1d","1o1d","w2d","3d","wor1","1or1","w1r1","2r1","wo2","1o2","w3","4"]

我們可以對上面程式碼稍稍改寫一下,變的稍微簡潔一點: 

解法二:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        for (int i = 0; i < pow(2, word.size()); ++i) {
            string out = "";
            int cnt = 0;
            for (int j = 0; j < word.size(); ++j) {
                if ((i >> j) & 1) ++cnt;
                else {
                    if (cnt != 0) {
                        out += to_string(cnt);
                        cnt = 0;
                    }
                    out += word[j];
                }
            }
            if (cnt > 0) out += to_string(cnt);
            res.push_back(out);
        }
        return res;
    }
};

那麼迭代的寫法看完了,來考慮一些遞迴的寫法吧,上網搜了一下,發現下面三種寫法比較容易理解, 

解法三:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res{word};
        helper(word, 0, res);
        return res;
    }
    void helper(string word, int pos, vector<string> &res) {
        for (int i = pos; i < word.size(); ++i) {
            for (int j = 1; i + j <= word.size(); ++j) {
                string t = word.substr(0, i);
                t += to_string(j) + word.substr(i + j);
                res.push_back(t);
                helper(t, i + 1 + to_string(j).size(), res);
            }
        }
    }
};

上述方法返回結果的順序為:

["word","1ord","1o1d","1o2","1or1","2rd","2r1","3d","4","w1rd","w1r1","w2d","w3","wo1d","wo2","wor1"]

解法四:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        helper(word, 0, 0, "", res);
        return res;
    }
    void helper(string word, int pos, int cnt, string out, vector<string> &res) {
        if (pos == word.size()) {
            if (cnt > 0) out += to_string(cnt);
            res.push_back(out);
        } else {
            helper(word, pos + 1, cnt + 1, out, res);
            helper(word, pos + 1, 0, out + (cnt > 0 ? to_string(cnt) : "") + word[pos], res);
        }
    }
};

上述方法返回結果的順序為:

 ["4","3d","2r1","2rd","1o2","1o1d","1or1","1ord","w3","w2d","w1r1","w1rd","wo2","wo1d","wor1","word"]

解法五:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        res.push_back(word.size() == 0 ? "" : to_string(word.size()));
        for (int i = 0; i < word.size(); ++i) {
            for (auto a : generateAbbreviations(word.substr(i + 1))) {
                string left = i > 0 ? to_string(i) : "";
                res.push_back(left + word.substr(i, 1) + a);
            }
        }
        return res;
    }
};

上述方法返回結果的順序為:

["4","w3","wo2","wor1","word","wo1d","w1r1","w1rd","w2d","1o2","1or1","1ord","1o1d","2r1","2rd","3d"]

參考資料: