英文名字:
Letter Combinations of a Phone Number
模糊的单词
- digit 数字
- combination 组合
- represent 代表
- lexicographical order 字典序
深度优先搜索
注意,每一次最深递归就是一个cur,也就是一个树枝
深搜也是每一个结点的值做笛卡尔积的过程。
多少个cur=多少个结果=多少个dfs的return
这道题dfs函数前后只是栈的变化,通过控制l深度,只会找l之后的。
class Solution {
public:
// 实际上也是求所有的数字mapping的笛卡尔积
vector<string> letterCombinations(string digits) {
if(digits.empty()){return {};}
// 这里面写所有的输入
vector<vector<char>> d(10);
// d[0]={''};
// d[1]={};
d[2]={'a','b','c'};
d[3]={'d','e','f'};
d[4]={'g','h','i'};
d[5]={'j','k','l'};
d[6]={'m','n','o'};
d[7]={'p','q','r','s'};
d[8]={'t','u','v'};
d[9]={'w','x','y','z'};
vector<string> ans;
string cur;
dfs(digits,d,cur,0,ans); // 作用将所有的结果存入ans
return ans;
}
private:
// dfs一层层向下延展,就是往深处递归,脑子中应该呈现出一个树形
void dfs(const string& digits,const vector<vector<char>>& d,string& cur,int l,vector<string>& ans){
// 递归出口 这道题的出口是 树的深度达到一定 需要定义一个l记录深度
if(l == digits.length()){
ans.push_back(cur);
return;
}
// 定义一个存储的栈,达到条件就入栈,
// 让每一个数字的对应的多个value依次 向内递归,
// 树每一个分支出来的只是一个结果,结果组合起来就是笛卡尔积
for(char c:d[digits[l]-'0']){
// 字符串可以直接当做栈用
cur.push_back(c);
dfs(digits,d,cur,l+1,ans);
// 算完需要弹出 改变,到原来的状态,保持char c的多种情况dfs时的状态一致
cur.pop_back();
}
}
};
广度优先搜索
// 方法二:BFS
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public:
// 实际上也是求所有的数字mapping的笛卡尔积
vector<string> letterCombinations(string digits) {
if(digits.empty())
return {};
vector<string> ans{""};// 长度最少为1,要不不进入循环了
vector<vector<char>> d(10);
d[2]={'a','b','c'};
d[3]={'d','e','f'};
d[4]={'g','h','i'};
d[5]={'j','k','l'};
d[6]={'m','n','o'};
d[7]={'p','q','r','s'};
d[8]={'t','u','v'};
d[9]={'w','x','y','z'};
for(char c:digits){ // 每深入一层就把tmp换一下
vector<string> tmp; // 为什么不在ans里面直接加工
// 做笛卡尔积的时候 数量会翻倍。。又不是单层循环每个元素 加一。
for(string& childAns:ans){ //""
for(char eve:d[c-'0']) // "a","b","c" 算出每一个分支的笛卡尔积
tmp.push_back(childAns+eve); // 将字母压入每一个结果string
// 将每个分支的结果压入
}
ans.swap(tmp);
}
return ans;
}
};
//leetcode submit region end(Prohibit modification and deletion)