组合板子+剪枝
216. 组合总和 III
class Solution {
private:
vector<int>temp;
vector<vector<int>>result;
//sum 存和,index为回溯提供下标
void backtracking(int k,int n,int sum,int index)
{
if(temp.size() == k)//判断一维数组的个数是否等于k
{
if(sum == n ) //等于所求值 存入,佛则返回上一层;
{
result.push_back(temp);
}
return; //如果不符合要求,返回上一层
}
for(int i=index;i<=9;i++)//无剪枝版(第一次1~9种情况)
{
sum+=i;//和值改变
temp.push_back(i);//存入i
backtracking(k,n,sum,i+1);//i+1让范围向后推1 例如2~9
sum-=i;//回溯过程
temp.pop_back();
}
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,0,1);
return result;
}
};
剪枝操作?
1.想想如果sum已经超过了,目标值但此时一维数组个数还没有达到k
我们直接return上一层!
2.如果我们不能让一维数组的个数到k,我们是不是直接把这个分支剪掉,避免非必要循环!
例如:我们要求 k=2,但是递归到 9已经没有意义!
k=3,我们递归到7就可以,{7.8.9}后面已经没有必要了去递归了,因为怎么递归都满足不了size=k;
所以怎么递归?
我们把9-(k-size)//假设k=2,第一次size=0所以9-(2-0)=7,我们要递归到8,所以9-(k-size)+1
假设k=3,9-(k-size)+1=7,第一次正好遍历到7
第二次size已经+1,则9-(k-size)+1=8,则8,同理下一次为9,所以遍历为{7,8,9}
class Solution {
private:
vector<int>temp;
vector<vector<int>>result;
//sum 存和,index为回溯提供下标
void backtracking(int k,int n,int sum,int index)
{
if(sum>n) return;
if(temp.size() == k)//判断一维数组的个数是否等于k
{
if(sum == n ) //等于所求值 存入,佛则返回上一层;
{
result.push_back(temp);
}
return; //如果不符合要求,返回上一层
}
for(int i=index;i<=9-(k-temp.size())+1;i++)//无剪枝版(第一次1~9种情况)
{
sum+=i;//和值改变
temp.push_back(i);//存入i
backtracking(k,n,sum,i+1);//i+1让范围向后推1 例如2~9
sum-=i;//回溯过程
temp.pop_back();
}
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,0,1);
return result;
}
};
17. 电话号码的字母组合
class Solution {
private:
const string keys[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
string s;
vector<string>result;
//index 无比重要,它是确定到输入字符串数组遍历到哪里了!
//"23",index=0,说明是2,index=1,说明是3
void backtarcking(const string &digits,int index)
{
if( index == digits.size())//index在“23”情况不是到1就行了吗?我们在“23”后面进入下一次index已经等于2了,直接return!而且回溯正确
{result.push_back(s);
return;
}
int stand=digits[index]-'0';//index妙用,stand可以实现9键的按键
string tempS=keys[stand];//对应按键字符串!
for(int i=0;i<tempS.size();i++)
{
s.push_back(tempS[i]);
backtarcking(digits,index+1);//index+1,移动到“3”;
s.pop_back();//回溯
}
}
public:
vector<string> letterCombinations(string digits) {
if(digits.size()==0)
return result;
backtarcking(digits,0);//index为1
return result;
}
};