此题是面试遇见的一道题,当时出的是笛卡尔积,和这个其实道理是一样的。
此题如果用标准的回溯做,是会出问题的。一开始做的时候,我是把他当全排列做的。
但全排列是没有重复状态的,每次选一个。一个状态的前继状态只有一种可能。但笛卡尔积问题是不止一个前继状态,有重复节点就很难记录,所以此题采用迭代+队列来做是最好的。
class Solution {
public:
vector<string> letterCombinations(string digits) {
int n = digits.size();
vector<string> ans;
if(n == 0)return ans;
vector<string> v{"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
queue<string> q;
q.push("");
for(auto d: digits)
{
int n = q.size();
string cand = v[d-'2'];
for(int i=0;i<n;i++)
{
string s = q.front(); q.pop();
for(auto c: cand)
{
q.push(s+c);
}
}
}
while(!q.empty())
{
ans.push_back(q.front());
q.pop();
}
return ans;
}
};
解法二:dfs
当时的我咋这么年轻呢,dfs都做这么久,直接上代码解决~ 此外,还有map的初始化方式,还是挺方便的。
class Solution {
map<int, string> m = {{2, "abc"}, {3, "def"}, {4, "ghi"}, {5, "jkl"},
{6, "mno"}, {7, "pqrs"}, {8, "tuv"}, {9, "wxyz"}};
public:
void dfs(vector<string>& ans, string tmp, string digits, int pos)
{
if(pos >= digits.size())
{
ans.push_back(tmp);
return;
}
auto lst = m[digits[pos] - '0'];
for(auto c: lst)
{
tmp += c;
dfs(ans, tmp, digits, pos+1);
tmp.pop_back();
}
}
vector<string> letterCombinations(string digits) {
vector<string> ans;
if(digits.size() == 0)return ans;
dfs(ans, "", digits, 0);
return ans;
}
};