代码随想录Day25 | 216.组合总和III 17.电话号码的字母组合
216.组合总和III
文档讲解:代码随想录
视频讲解: 和组合问题有啥区别?回溯算法如何剪枝?
状态:
本题相较于昨天的组合问题,增加了一个约束就是和等于n才能放入,其余的不变, 终止条件和递归逻辑都是一样的。我是采用的最后求和的方法,而代码随想录中,将和作为参数传入到下一层中,可以方便剪枝处理,剪枝的判断要注意是否需要回溯,如果添加了元素就需要回溯
//从1,2,3,4,5,6,7,8,9这个数组中向下递归k层
//如果获得的k个数相加等于n
//这添加组合
class Solution {
private:
vector<int> path;
vector<vector<int>> res;
public:
void getPath(int MaxNum, int n, int k, int targetIndex)
{
//终止条件
if(path.size() == k)
{
int sum = 0;
for(int i=0;i<k;i++)
{
sum += path[i];
}
if(sum == n)
{
res.push_back(path);
}
return ;
}
//单层递归 遍历
for(int i=targetIndex;i<=MaxNum-(k-path.size())+1;i++)
{
path.push_back(i);
getPath(MaxNum,n,k,i+1);
path.pop_back();
}
return ;
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
//vector<int> nums{1,2,3,4,5,6,7,8,9};
int MaxNum = 9;
getPath(MaxNum,n,k,1);
return res;
}
};
17.电话号码的字母组合
文档讲解:代码随想录
视频讲解: 还得用回溯算法!| LeetCode:17.电话号码的字母组合
状态:
本题向下递归的层数就是digits的size,然后顺序是按照digits的顺序,每层遍历的为digits[i]对应的多个字母,这里采用unordered_map来进行映射数字和字符串的关系
//向下递归层数即为digits的size
//顺序按照digits顺序
//每层遍历的为digits[i]对应的多个字母
class Solution {
private:
vector<string> res;
string path;
unordered_map<int ,string> transmap;
public:
void getPath(string digits,int Index)
{
if(path.size() == digits.size())
{
res.push_back(path);
return ;
}
//单层递归
int i = digits[Index] - '0';
//对该层的每个字母遍历
for(char s : transmap.find(i)->second)
{
path.push_back(s);
//向下递归求下一个位置的字符
getPath(digits,Index+1);
path.pop_back();
}
return ;
}
public:
vector<string> letterCombinations(string digits) {
if(digits == "") return vector<string> {};
for(char s : digits)
{
int i = s-'0';
string temp;
if(i==2)
{
temp = "abc";
}
else if(i == 3)
{
temp = "def";
}
else if(i == 4)
{
temp = "ghi";
}
else if(i == 5)
{
temp = "jkl";
}
else if(i == 6)
{
temp = "mno";
}
else if( i == 7)
{
temp = "pqrs";
}
else if(i == 8)
{
temp = "tuv";
}
else if(i == 9)
{
temp = "wxyz";
}
transmap.insert(pair<int,string>(i,temp));
}
getPath(digits,0);
return res;
}
};
对于输入异常情况 就是输入的不是2-9,也需要进行映射,来处理输出情况