一:题目
、
二:思路
①:用递归解决,因为这就是一个多叉树的深度优先遍历
②:递归函数的参数:
参数1:digits,也就是"23"这种已知条件
参数2:一个整形叫作di,用来表示digits的下标,以便获取每个电话号码对应的字符串
参数3:一个字符串cbstr,用来表示每次递归得到的字符串
参数4:题目返回的是一个vector<string>,也就是一个字符串数组,所以我们单次递归到终点得到的结果应该被push_back进这个数组中,所以参数还有一个vector<string>类型的对象
三:代码解析
解释:
①:参数digits用引用传递,是单纯的省略拷贝,也可以不用
②:d1不能用引用传递和取地址传递,因为当递归返回时,需要撤销上一步的修改(即回溯)
③:cbstr也是和②一样,当递归返回时,需要撤销上一步的修改(即回溯),以便尝试其他可能的字母,
如果 cbstr
是引用传递:
每次递归调用都会修改同一个 cbstr
对象。
当递归返回时,cbstr
的状态已经被修改,无法正确回溯。
且cbstr 在函数中用+不能用+=,因为不能影响自身,当递归返回时,需要撤销上一步的修改(即回溯),以便尝试其他可能的字母,
④:v必须引用传递,因为该值从递归深回到递归浅层次的时候,依旧要保留上一次递归到最深处所push_back的字符串
如果 v
不使用引用传递:
每次递归调用都会创建一个新的 v
副本。
递归调用中对 v
的修改(例如 v.push_back(cbstr)
)只会作用于副本,而不会影响原始 的 v
。
最终,原始的 v
仍然是空的,无法得到正确的结果。
四:源码
class Solution {
public://一个字符串数组来让电话号码作为下标精准对应字符串 两个空字符串让2对准了"abc"string Num_To_Str[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};void Combine(string& digits,int di,string cbstr,vector<string>& v){if(di == digits.size())//表明digits这个数组已经被遍历完成,目前是超过的一次,{ //也就是说:该次递归已达最深,得到一个完全的字符串,将其push_back进v中v.push_back(cbstr);return ;}int i = digits[di]-'0';//获取digits这个字符串里面的字符 -'0'转换为int值,得到单个电话号码string str = Num_To_Str[i];//将电话号码作为Num_To_Str下标得到对应的字符串for(int j=0; j<str.size(); j++)//电话号码对应的字符串会在整个递归的过程中逐渐被全部遍历{Combine(digits,di+1,cbstr+str[j],v);} // 下标+1 cbstr字符串获取到了每次该获取到的一个字符}vector<string> letterCombinations(string digits) {vector<string> v;//v是最后的返回值 该字符数组存储了类似["ad","ae","af","bd","be","bf","cd","ce","cf"]的值if(digits.empty())//如果电话号码都没有return v;则返回vCombine(digits,0,"",v);//第一次调用递归函数return v;}
};