题目链接:216.组合总和III
这道题与第77题组合非常相像,相对来说加了元素总和的限制,这里把问题抽象为树形结构,按照回溯三部曲进行解答,最后给出剪枝的优化。
代码如下:
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backTacking(int k,int n,int sum,int startIndex)
{
if (sum >n)
return;
if(path.size()==k)
{
if(sum==n) result.push_back(path);
return;
}
for(int i=startIndex;i<=9;i++)
{
sum+=i;
path.push_back(i);
backTacking(k,n,sum,i+1);
sum-=i;
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
backTacking(k,n,0,1);
return result;
}
};
题目链接:17.电话号码的字母组合
这道题也是按照三部曲来进行解答的,
注意这道题中的for循环,并不是像在回溯算法:求组合问题! (opens new window)和回溯算法:求组合总和! (opens new window)中从startIndex开始遍历的。
因为本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,而77. 组合 (opens new window)和216.组合总和III (opens new window)都是求同一个集合中的组合!
代码如下:
class Solution {
private:
const string letterMap[10]={
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
public:
vector<string> result;
string path;
void backTacking(string& digits,int index)
{
if(digits.size()==index)
{
result.push_back(path);
return;
}
int digit=digits[index]-'0';
string letter=letterMap[digit];
for(int i=0;i<letter.size();i++)
{
path.push_back(letter[i]);
backTacking(digits,index+1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
result.clear();
path.clear();
if(digits.size()==0) return result;
backTacking(digits,0);
return result;
}
};