216.组合总和III
这道题目在组合的基础上做会比较容易,这道题目的不同之处在于,for循环的范围是固定的1-9,
其剪枝的操作有两点:
1. 累加和大于目标n,可以直接返回;
2. for循环的最大值类似于组合这道题目:i<=9-(k-path.size())+1;
详细代码如下:
class Solution
{
public:
int sum = 0;
vector<int> path;
vector<vector<int>> res;
void backtracking(int n, int k, int startindex)
{
//pruning 1
if (sum > n) return;
//end
if (path.size()==k)
{
if(sum == n) res.push_back(path);
return;
}
//backtrack
//for (int i = startindex; i <= 9; i++)
//pruning 2
for (int i = startindex; i <= 9-(k-path.size())+1; i++)
{
path.push_back(i);
sum += i;
backtracking(n, k, i + 1);
sum -= i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n)
{
backtracking(n, k, 1);
return res;
}
};
17.电话号码的字母组合
这道题要解决三个问题:
1. 如何表述数字到字母的映射:用数组表示;
2. 遇到异常输入怎么办?直接返回;
3. 回溯具体怎么写?对每个数字对应的letter进行遍历,用一个参数index来表示目前是第几个数字;
详细代码如下:
class Solution
{
private:
vector<string> letter_map =
{
"", //0
"", //1
"abc", //2
"def", //3
"ghi", //4
"jkl", //5
"mno", //6
"pqrs",//7
"tuv", //8
"wxyz" //9
};
public:
vector<string> res;
string s;
void backtrack(string digits, int index)
{
//end
if (index == digits.size())
{
res.push_back(s);
return;
}
//process
int dig = digits[index] - '0'; //get index
if (dig < 2 || dig>9) return; //error
string letter = letter_map[dig];
for (int i = 0; i < letter.size(); i++)
{
s.push_back(letter[i]);
backtrack(digits, index + 1);
s.pop_back();
}
}
vector<string> letterCombinations(string digits)
{
if(digits.size()==0) return {};
backtrack(digits, 0);
return res;
}
};