题目
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];
}