# day 9 回溯算法

77. 组合

class Solution {
public:
vector<int> path;
vector<vector<int>> res;
//确定递归函数参数和返回值
void backtracking(int n,int k,int startIndex){
//确定终止条件
if(path.size()==k){
res.push_back(path);
return;
}

//确定单层递归逻辑
for(int i=startIndex;i<=n;i++){
path.push_back(i);
backtracking(n,k,i+1);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n,k,1);
return res;
}
};

class Solution {
public:
vector<int> path;
vector<vector<int>> res;
//确定递归函数参数和返回值
void backtracking(int n,int k,int startIndex){
//确定终止条件
if(path.size()==k){
res.push_back(path);
return;
}

//确定单层递归逻辑
for(int i=startIndex;i<=n-(k-path.size())+1;i++){//优化的地方
path.push_back(i);
backtracking(n,k,i+1);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n,k,1);
return res;
}
};

216. 组合总和 III

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(int k,int n,int startIndex){
//确定终止条件
if(path.size()==k){
if(n==0){
res.push_back(path);
return;
}
}

//确定单层递归逻辑
for(int i=startIndex;i<=9;i++){
n-=i;
path.push_back(i);
backtracking(k,n,i+1);
path.pop_back();
n+=i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,1);
return res;
}
};

1.目标数n一直在随i的加入减小，如果目标数n已经<0，那么剪枝。即path中的数已经大于目标数了。

2.对for循环i的遍历范围进行缩小

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(int k,int n,int startIndex){
//优化：剪枝
if(n<0) return;
//确定终止条件
if(path.size()==k){
if(n==0){
res.push_back(path);
return;
}
}

//确定单层递归逻辑
for(int i=startIndex;i<=10-(k-path.size());i++){//剪枝 优化
n-=i;
path.push_back(i);
backtracking(k,n,i+1);
path.pop_back();
n+=i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,1);
return res;
}
};
class Solution {
public:
const string letterMap[10]={
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
vector<string> res;
string s;
//确定递归函数参数和返回值
void backtracing(const string& digits,int index){
//确定终止条件
if(index==digits.size()){
res.push_back(s);
return;
}

//确定单层递归逻辑
int num=digits[index]-'0';
//string str=letterMap[num];
string strr=letterMap[num];
for(int i=0;i<strr.size();i++){
s.push_back(strr[i]);
backtracing(digits,index+1);
s.pop_back();
}

}
vector<string> letterCombinations(string digits) {
if(digits.size()==0){
return res;
}
backtracing(digits,0);
return res;
}
};

39. 组合总和

class Solution {
public:
vector<int> path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& candidates,int target,int startIndex){
//确定终止条件
if(target<0) return;
if(target==0) {
res.push_back(path);
return;
}

//确定单层递归逻辑
for(int i=startIndex;i<candidates.size();i++){
target-=candidates[i];
path.push_back(candidates[i]);
backtracking(candidates,target,i);
target+=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0);
return res;
}
};

class Solution {
public:
vector<int> path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& candidates,int target,int startIndex){
//确定终止条件
if(target==0) {
res.push_back(path);
return;
}

//确定单层递归逻辑
for(int i=startIndex;i<candidates.size()&&target-candidates[i]>=0;i++){
target-=candidates[i];
path.push_back(candidates[i]);
backtracking(candidates,target,i);
target+=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,0);
return res;
}
};

40. 组合总和 II

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& candidates,int target,vector<bool>st,int startIndex){
//确定终止条件
if(target<0)return;
if(target==0){
res.push_back(path);
return;
}

//确定单层递归逻辑
for(int i=startIndex;i<candidates.size();i++){
if(i>0&&candidates[i]==candidates[i-1]&&st[i-1]==false){
continue;
}//对组合去重
path.push_back(candidates[i]);
st[i]=true;
target-=candidates[i];
backtracking(candidates,target,st,i+1);
path.pop_back();
st[i]=false;
target+=candidates[i];
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool>st(candidates.size(),false);
sort(candidates.begin(),candidates.end());
backtracking(candidates,target,st,0);
return res;
}
};

131. 分割回文串

class Solution {
public:
//确定是否是回文
bool isTrue(string s,int start,int end){
for(int i=start,j=end;i<j;){
if(s[i]!=s[j]){
return false;
}
else {
i++;
j--;
}
}
return true;
}
//确定递归函数参数和返回值
void backtracking(vector<string>& path,vector<vector<string>>& res,int startIndex,string s){
//确定终止条件
if(startIndex==s.size()){
res.push_back(path);
return;
}
//确定单层递归逻辑
for(int i=startIndex;i<s.size();i++){
if(isTrue(s,startIndex,i)){
string str=s.substr(startIndex,i-startIndex+1);
path.push_back(str);
}
else{
continue;
}
backtracking(path,res,i+1,s);
path.pop_back();
}
}
vector<vector<string>> partition(string s) {
vector<string>path;
vector<vector<string>>res;
backtracking(path,res,0,s);
return res;
}
};

93. 复原 IP 地址

class Solution {
public:
//确判断是否符合ip地址
bool isTrue(string s,int start,int end){
if(start>end) return false;
if(s[start]=='0'&&start!=end) return false;
int num=0;
for(int i=start;i<=end;i++){
if(s[i]<'0'||s[i]>'9') return false;
num=num*10+(s[i]-'0');
if(num>255)return false;
}
return true;
}
//确定递归函数参数和返回值
void backtracking(string &s,int startIndex,int pointNum,vector<string>&res){
//确定终止条件
if(pointNum==3){
if(isTrue(s,startIndex,s.size()-1)){
res.push_back(s);
}
return;
}
//确定单层递归逻辑
for(int i=startIndex;i<s.size();i++){
if(isTrue(s,startIndex,i)){
s.insert(s.begin()+i+1,'.');
pointNum+=1;
backtracking(s,i+2,pointNum,res);
pointNum-=1;
s.erase(s.begin()+i+1);
}
else break;
}
}
vector<string>res;
if(s.size()<4||s.size()>12) return res;
backtracking(s,0,0,res);
return res;
}
};

78. 子集

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(int startIndex,vector<int>nums){
res.push_back(path);//不会漏掉自己，空集
//确定终止条件
if(startIndex>=nums.size()) return;

//确定单层递归逻辑
for(int i=startIndex;i<nums.size();i++){
path.push_back(nums[i]);
backtracking(i+1,nums);
path.pop_back();

}
}
vector<vector<int>> subsets(vector<int>& nums) {
backtracking(0,nums);
return res;
}
};

90. 子集 II

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>nums,int startIndex,vector<bool>&st){
res.push_back(path);
//确定终止条件
if(startIndex>=nums.size())return;

//确定单层递归逻辑
for(int i=startIndex;i<nums.size();i++){
if(i>0&&nums[i]==nums[i-1]&&st[i-1]==false){
continue;
}
path.push_back(nums[i]);
st[i]=true;
backtracking(nums,i+1,st);
path.pop_back();
st[i]=false;
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> st(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,0,st);
return res;
}
};

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>nums,int startIndex){
res.push_back(path);
//确定终止条件
if(startIndex>=nums.size())return;

//确定单层递归逻辑
for(int i=startIndex;i<nums.size();i++){
if(i>startIndex&&nums[i]==nums[i-1]){
continue;
}
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
backtracking(nums,0);
return res;
}
};

491. 非递减子序列

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& nums,int startIndex){
if(path.size()>1){
res.push_back(path);
}
//确定终止条件
if(startIndex>=nums.size()){
return;
}

//确定单层递归逻辑
unordered_set<int> uset;//对每层去重
for(int i=startIndex;i<nums.size();i++){
if((!path.empty()&&nums[i]<path.back())||uset.find(nums[i])!=uset.end()){
continue;
}
uset.insert(nums[i]);//记录该元素在本层用过了，之后的相同元素不再使用
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return res;
}
};

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& nums,int startIndex){
if(path.size()>1){
res.push_back(path);
}
//确定终止条件
if(startIndex>=nums.size()){
return;
}

//确定单层递归逻辑
int st[201]={0};//对每层去重
for(int i=startIndex;i<nums.size();i++){
if((!path.empty()&&nums[i]<path.back())||st[nums[i]+100]==1){
continue;
}
st[nums[i]+100]=1;;//记录该元素在本层用过了，之后的相同元素不再使用
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return res;
}
};

46. 全排列

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& nums,vector<bool>& st){
//确定终止条件
if(path.size()==nums.size()){
res.push_back(path);
return;
}
//确定单层递归逻辑
for(int i=0;i<nums.size();i++){
if(st[i]==true) continue;
st[i]=true;
path.push_back(nums[i]);
backtracking(nums,st);
path.pop_back();
st[i]=false;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> st(nums.size(),false);
backtracking(nums,st);
return res;
}
};

47. 全排列 II

class Solution {
public:
vector<int>path;
vector<vector<int>>res;
//确定递归函数参数和返回值
void backtracking(vector<int>& nums,vector<bool>& st){
//确定终止条件
if(path.size()==nums.size()){
res.push_back(path);
return;
}
//确定单层递归逻辑
for(int i=0;i<nums.size();i++){
if(i>0&&nums[i]==nums[i-1]&&st[i-1]==false){
continue;//树层去重的
}
if(st[i]==true) continue;//树枝去重
st[i]=true;
path.push_back(nums[i]);
backtracking(nums,st);
path.pop_back();
st[i]=false;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<bool>st(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,st);
return res;
}
};

332. 重新安排行程

class Solution {
public:
//unordered_map<出发机场,map<到达机场,航班次数>>targets;
unordered_map<string,map<string,int>>targets;
//确定递归函数参数和返回值
bool backtracking(int ticketNum,vector<string>& res){
//确定终止条件
if(res.size()==ticketNum+1){
return true;
}
//确定单层递归逻辑
for(pair<const string, int>&target:targets[res[res.size()-1]]){
if(target.second>0){//记录到达机场是否飞过了
res.push_back(target.first);
target.second--;
if(backtracking(ticketNum,res)) return true;
res.pop_back();
target.second++;
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string>res;
for(const vector<string>& vec:tickets){
targets[vec[0]][vec[1]]++;//记录映射关系

}
res.push_back("JFK");
backtracking(tickets.size(),res);
return res;
}
};

51. N 皇后

class Solution {
public:
vector<vector<string>>res;
//判断位置是否合法
bool isValid(int n,int col,int row,vector<string>& chessBorad){
//同一列
for(int i=row-1;i>=0;i--){
}
//东北夹角
for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++){
}
//西北夹角
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
}
return true;
}
//确定递归函数参数和返回值
//确定终止条件
if(n==row){
return ;
}

//确定单层递归逻辑
for(int col=0;col<n;col++){
continue;
}
else{
}
}

}
vector<vector<string>> solveNQueens(int n) {
return res;
}
};

37. 解数独

class Solution {
public:
bool isValid(int row,int col,char val,vector<vector<char>>& board){
//行判断
for(int i=0;i<9;i++){
if(board[row][i]==val) return false;
}
//列判断
for(int i=0;i<9;i++){
if(board[i][col]==val) return false;
}
//九宫格内判断
row=(row/3)*3;
col=(col/3)*3;
for(int i=row;i<row+3;i++){
for(int j=col;j<col+3;j++){
if(board[i][j]==val) return false;
}
}
return true;
}
bool backtracking(vector<vector<char>>& board){
//不需要单独的终止条件，不需要收集结果
//确定单层递归逻辑
for(int row=0;row<board.size();row++){
for(int col=0;col<board[0].size();col++){
if(board[row][col]=='.'){
for(char val='1';val<='9';val++){
if(isValid(row,col,val,board)){
board[row][col]=val;
if(backtracking(board)) return true;
board[row][col]='.';
}
}
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};

• 6
点赞
• 4
收藏
觉得还不错? 一键收藏
• 0
评论
11-10 1209
03-18 449
06-28 439
11-21 123
08-07 1068
02-11 439
01-29 486
12-01 689
05-17 326
11-25 784
10-21 6726
09-08 1414
09-07 1195
09-11 336
09-12 863

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。