LeetCode 216. 组合总和 |||
解题思路
本题与“组合”题目很相似,都是寻找k个数,但是本题要求这k个数的和为n。 另外两道题目的集合范围也不一样。本题是从1~9中进行取值。
本题主要修改的点包括两方面:
- 终止条件需要变成:找到k个数之后,如果和为n直接保存;如果he不等于k,跳出该循环;
- 处理结点以及回溯的时候要加上 sum 的处理操作。
代码解析
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
int sum = 0;
void backtracking(int k, int n, int startIndex)
{
if(path.size() ==k )
{
if(sum == n)
{
result.push_back(path);
}
return ;
}
// else
// {}
for(int i = startIndex; i<10; i++)
{
path.push_back(i);
sum +=i;
backtracking(k, n, i+1);
path.pop_back();
sum -=i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k, n, 1);
return result;
}
};
LeetCode 17. 电话号码的字母组合
解题思路
根据示例,每次取digits中每个数字对应字符的一个字符,所以本题需要解决三个问题:
- 数字和字母如何映射;
- 两个字母两个for循环,三个字符三个for循环。。。。;
- 输入1 * # 等异常情况;
数字和字母如何映射
可以使用map 或者定义一个二维数组做映射(数组的使用有些遗忘,需要补一下)。
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
回溯法解决n个for循环的问题
可以看出,本题的不同在于孩子结点 的集合范围和父结点没有关系, 所以在循环开始之前首先要求出集合,即通过映射关系拿到对应的字符串。
代码解析
class Solution {
public:
// 数组初始化
string numbers[10]= {
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"
};
vector<string> result;
string digit;
void backtracking(string digits, int index)
{
if(digit.size() == digits.size())
{
result.push_back(digit);
return ;
}
// cout<< ;
// char型转化成int型
string symbols = numbers[digits[index] - '0'];
cout << symbols;
for(int i = 0; i<symbols.size(); i++)
{
digit+=symbols[i];
backtracking(digits, index+1);
digit.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size() ==0)
return result;
backtracking(digits, 0);
return result;
}
};