leetcode 17 電話號碼的字母組合(Letter Combinations of a Phone Number)

題目

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example:

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路

題目的本質是多維數組展開爲一維數組,每個數字對應的字符串的長度就是該維的大小,以234爲例,3個數字對應的字符串長度都爲3,因此三位數組每一維的大小就是3,我們要做的就是把這個3維數組展開爲一維,將一維數組索引轉換爲3維。

一維數組索引 三維數組索引
0 0,0,0
1 0,0,1
8 0,2,2
9 1,0,0
26 2,2,2

代碼

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        map<char, string> int2str;
        buildInt2Str(int2str);
        
        vector<int> multis;
        int multi = 1;
        for (int i = digits.size() - 2; i >= 0; --i) {
            multi *= int2str[digits[i + 1]].size();
            multis.insert(multis.begin(), multi);
        }
        
        vector<string> res;
        for (int i = 0; i < multi * int2str[digits[0]].size(); ++i) {
            string s("");
            for (int j = 0; j < digits.size() - 1; ++j) {
                int idx = i / multis[j];
                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
                s += int2str[digits[j]][idx];
            }
            string last = int2str[digits[digits.size() - 1]];
            s += last[i % last.size()];
            res.push_back(s);
        }
        
        return res;
    }
private:
    void buildInt2Str(map<char, string> &int2str) {
        int2str.insert(pair<char, string>('2', "abc"));
        int2str.insert(pair<char, string>('3', "def"));
        int2str.insert(pair<char, string>('4', "ghi"));
        int2str.insert(pair<char, string>('5', "jkl"));
        int2str.insert(pair<char, string>('6', "mno"));
        int2str.insert(pair<char, string>('7', "pqrs"));
        int2str.insert(pair<char, string>('8', "tuv"));
        int2str.insert(pair<char, string>('9', "wxyz"));
    }
};

構造數字到字符串的映射表

        map<char, string> int2str;
        buildInt2Str(int2str);

獲取每一維數組大小

        vector<int> multis;
        int multi = 1;
        for (int i = digits.size() - 2; i >= 0; --i) {
            multi *= int2str[digits[i + 1]].size();
            multis.insert(multis.begin(), multi);
        }

以234數組爲例,第一維大小爲12=3*4,第二維大小爲4,第三維直接取下標

根據一維下標獲取三維數組下標

        vector<string> res;
        for (int i = 0; i < multi * int2str[digits[0]].size(); ++i) {
            string s("");
            for (int j = 0; j < digits.size() - 1; ++j) {
                int idx = i / multis[j];
                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
                s += int2str[digits[j]][idx];
            }
            string last = int2str[digits[digits.size() - 1]];
            s += last[i % last.size()];
            res.push_back(s);
        }

注意,在獲取第1~(n-1)維的下標時,需要先對前一維的數組大小取餘:

                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章