代码随想录|回溯法2刷

news/2025/3/14 19:15:00/

第77题. 组合

链接:代码随想录

class Solution {
public:vector<vector<int>> v;vector<int>res;vector<vector<int>> combine(int n, int k) {backtracing(n,1,k);return v;}void backtracing(int n,int startIndex,int k){if(res.size()==k){v.push_back(res);//res.clear();return;}for(int j=startIndex;j<=n;j++){res.push_back(j);backtracing(n,j+1,k);res.pop_back();}}
};

剪枝:

class Solution {
public:vector<vector<int>> v;vector<int>res;vector<vector<int>> combine(int n, int k) {backtracing(n,1,k);return v;}void backtracing(int n,int startIndex,int k){if(res.size()==k){v.push_back(res);//res.clear();return;}for(int j=startIndex;j<=n - (k - res.size()) + 1;j++){res.push_back(j);backtracing(n,j+1,k);res.pop_back();}}
};

216. 组合总和 III

链接:力扣

 

 剪枝注意:

class Solution {
public:vector<vector<int>>v;vector<int>res;vector<vector<int>> combinationSum3(int k, int n) {backtracing(k,n,1);return v;}void backtracing(int k,int n,int startIndex){if(res.size()==k && n==0){v.push_back(res);}for(int j=startIndex;j<=9-(k-res.size())+1;j++){res.push_back(j);if(n-j>=0){backtracing(k,n-j,j+1);}res.pop_back();}}
};

a

17.电话号码的字母组合 

链接:力扣

 

 自己的做法:

class Solution {
public:vector<string>v;vector<string>res;string str;vector<string> letterCombinations(string digits) {if(digits==""){return v;}v.push_back("abc");v.push_back("def");v.push_back("ghi");v.push_back("jkl");v.push_back("mno");v.push_back("pqrs");v.push_back("tuv");v.push_back("wxyz");backtracing(v,0,digits);return res;}void backtracing(vector<string> &v,int digitsIndex,string &digits){if(digitsIndex==digits.size()){res.push_back(str);}else{string s=v[digits[digitsIndex]-'2'];cout<<s<<endl;for(int j=0;j<s.size();j++){str.push_back(s[j]);backtracing(v, digitsIndex+1,digits);str.pop_back();}}}
};

a

39. 组合总和 

链接:代码随想录

class Solution {
public:vector<vector<int>>v;vector<int>res;vector<vector<int>> combinationSum(vector<int>& candidates, int target) {int n=candidates.size();if(n==0){return v;}backtracing(candidates,target,0,n);return v;}void backtracing(vector<int> & candidates,int target,int startIndex,int n){if(target==0){v.push_back(res);}for(int j=startIndex;j<n;j++){if(target-candidates[j]>=0){res.push_back(candidates[j]);backtracing(candidates,target-candidates[j],j,n);res.pop_back();}}}
};

40.组合总和II

链接:代码随想录 

class Solution {
public:vector<vector<int>> v;vector<int>res;vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {int n=candidates.size();if(n==0){return v;}sort(candidates.begin(),candidates.end());backtracing(candidates,target,0,n);return v;}void backtracing(vector<int>& candidates, int target,int startIndex,int n){if(target==0){v.push_back(res);}for(int j=startIndex;j<n;j++){if(j>startIndex && candidates[j]==candidates[j-1]){continue;}if(target-candidates[j]>=0){res.push_back(candidates[j]);backtracing(candidates,target-candidates[j],j+1,n);res.pop_back();}}}
};

a

131.分割回文串 

链接:力扣

自己的解法,欣喜若狂的做对了

class Solution {//牢记分割回文串这道题是回溯//牢记是组合问题,而且startIndex就是隔板
public:vector<vector<string>> v;vector<string>res;vector<vector<string>> partition(string s) {int n=s.size();if(n==0){return v;}backtracing(s,0,n);return v;}void backtracing(string s,int startIndex,int n){if(startIndex==n){v.push_back(res);}for(int j=startIndex;j<n;j++){string str=s.substr(startIndex,j-startIndex+1);if(is_huiwen(str)){res.push_back(str);backtracing(s,j+1,n);res.pop_back();}}}bool is_huiwen(string &str){int right=str.size()-1;int left=0;while(left<right){if(str[left]!=str[right]){return false;}left++;right--;}return true;}
};

93.复原IP地址 

链接:代码随想录

 

挺震惊的,我写的还挺快的

class Solution {
public:vector<string>v;//string res="";vector<string> restoreIpAddresses(string s) {backtracing(s,0,s.size(),0,"");return v;}void backtracing(string &s,int startIndex,int n,int k,string res)//k代表已经加入的一个小数点个数{if(startIndex==n && k==4){res.pop_back();v.push_back(res);}for(int j=startIndex;j<n;j++){string str=s.substr(startIndex,j-startIndex+1);if(str.size()>1 && str[0]=='0'){continue;}if(str.size()<=3){int num=atoi(str.c_str());if(num>=0 && num<=255){backtracing(s,j+1,n,k+1,res+str+".");   }}}}
};

 a

 78. 子集

链接:代码随想录

 吓人。。。。今天的代码都是一次对

代码:

class Solution {
public:vector<vector<int>> v;vector<int>res;vector<vector<int>> subsets(vector<int>& nums) {int n=nums.size();backtracing(nums,0,n);return v;}void backtracing(vector<int>& nums,int startIndex,int n){if(res.size()<=n ){v.push_back(res);}for(int j=startIndex;j<n;j++){res.push_back(nums[j]);backtracing(nums,j+1,n);res.pop_back();}}
};

a

a

90. 子集 II

链接:力扣

 还是那套模板

class Solution {
public:vector<vector<int>>v;vector<int>mv;vector<vector<int>> subsetsWithDup(vector<int>& nums) {sort(nums.begin(),nums.end());backtracing(nums,0);return v;}void backtracing(vector<int> &nums,int startIndex){if(mv.size()<=nums.size()){v.push_back(mv);}for(int j=startIndex;j<nums.size();j++){if(j>startIndex && nums[j]==nums[j-1]){continue;}mv.push_back(nums[j]);backtracing(nums,j+1);mv.pop_back();}}
};

491.递增子序列 ---------没思路

链接:代码随想录

 看了答案,主要是横向扩展节点时要做约束

答案:

力扣

46.全排列 ----------------------写错,排列掌握的没有组合好

链接:代码随想录

错误写法:我也不知道咋发明的,还是理解上错误,貌似我这样写约束的是纵向,打印结果只有一种。但是正确解法是每个节点上横向扩展,比如【1,2,3】第一层已经选了1,那么就平等的试一下选2、选3,选完就used,也就是节点上横向扩展。

所以

class Solution {
public:vector<bool>used;vector<vector<int>>v;vector<int>res;vector<vector<int>> permute(vector<int>& nums) {int n=nums.size();used.resize(n,false);backtracing(nums,0,n);return v;}void backtracing(vector<int>&nums,int i,int n){if(i==n){v.push_back(res);}for(int j=0;j<n;j++){if(!used[j]){used[i]=true;res.push_back(nums[i]);backtracing(nums,i+1,n);res.pop_back();used[i]=false;}}}
};

正确答案:

class Solution {
public:vector<bool>used;vector<vector<int>>v;vector<int>res;vector<vector<int>> permute(vector<int>& nums) {int n=nums.size();used.resize(n,false);backtracing(nums,n);return v;}void backtracing(vector<int>&nums,int n){if(res.size()==n){v.push_back(res);}for(int j=0;j<n;j++){if(!used[j]){used[j]=true;res.push_back(nums[j]);backtracing(nums,n);res.pop_back();used[j]=false;}}}
};

a

 47.全排列||

 

class Solution {
public:
//关键词:可包含重复数字的序列 nums的排列问题
//排列:一定用到used数组。而且每一层都从0开始遍历,遍历used数组中未标记的
//可重,要先排序,对于横向展开的选择再去重,和组合思路一样
vector<vector<int>>v;
vector<int>mv;vector<vector<int>> permuteUnique(vector<int>& nums) {v.clear();mv.clear();vector<bool>used;used.resize(nums.size(),false);sort(nums.begin(),nums.end());//先排序再去重backtracing(nums,used);return v;}void backtracing(vector<int> &nums,vector<bool> &used){if(mv.size()==nums.size()){v.push_back(mv);}for(int j=0;j<nums.size();j++){if (j > 0 && nums[j] == nums[j - 1] && used[j- 1] == false) {continue;}if(used[j]==false){used[j]=true;mv.push_back(nums[j]);backtracing(nums,used);mv.pop_back();used[j]=false;}}}
};

51. N皇后

链接:代码随想录

class Solution {
public:vector<vector<string>>v;vector<string>board;vector<vector<string>> solveNQueens(int n) {board.resize(n,string(n,'.'));backtracing(board,0,n);return v;}void backtracing(vector<string>&board,int i,int n){if(i==n){v.push_back(board);}for(int j=0;j<n;j++){if(if_can(board,i,j,n)){board[i][j]='Q';backtracing(board,i+1,n);board[i][j]='.';}}}bool if_can(vector<string>&board,int i,int j,int n){//不同列for(int k=0;k<i;k++){if(board[k][j]=='Q'){return false;}}//左上角检查int x=i;int y=j;while(x>=0 && y>=0&&x<n &&y<n){if(board[x][y]=='Q'){return false;}x--;y--;}x=i;y=j;//右上角检查while(x>=0 && y>=0&&x<n &&y<n){if(board[x][y]=='Q'){return false;}x--;y++;}return true;}};

52. N 皇后 II-----应该没啥问题

链接:力扣

class Solution {
public://记录之前的Q的位置;vector<pair<int,int>>location;int cnt=0;int totalNQueens(int n) {backtracing(0,n);return cnt;}void backtracing(int i,int n){if(i==n){cnt++;}for(int j=0;j<n;j++){if(if_can(i,j,n)){location.push_back({i,j});backtracing(i+1,n);location.pop_back();}}}bool if_can(int i,int j,int n){//同一列for(auto p:location){//同一列if(p.second==j){return false;}//左上角  //右上角if(((i-p.first)==(j-p.second))||((i-p.first)==(p.second-j))){return false;}}return true;}
};

37. 解数独

链接:代码随想录 

大概看了一下答案,重点在于三次循环。

 错了一些,重点是回溯是一个bool,找到合适的立即返回结果,不合适的不返回。这样能防止超时。

class Solution {
public:void solveSudoku(vector<vector<char>>& board) {int n=board.size();int m=board[0].size();backtracing(board,n,m);}bool backtracing(vector<vector<char>>&board,int n,int m){for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(board[i][j]!='.'){continue;}for(int k='1';k<='9';k++){if(is_Valid(i,j,k,board)){board[i][j]=k;if (backtracing(board,n,m)) return true; // 如果找到合适一组立刻返回board[i][j]='.';}}return false;                           // 9个数都试完了,都不行,那么就返回false}}return true;}bool is_Valid(int i,int j,char ch,vector<vector<char>>&board){//同一列,检查for(int t=0;t<9;t++){if(board[t][j]==ch){return false;}}//同一行,检查for(int t=0;t<9;t++){if(board[i][t]==ch){return false;}}int n=i/3;int m=j/3;for(int t=n*3;t<n*3+3;t++){for(int k=3*m;k<3*m+3;k++){if(board[t][k]==ch){return false;}}}return true;}
};

 


http://www.ppmy.cn/news/632787.html

相关文章

转】因为贱,所以生活艰辛!告诉你们真相,你们会更绝望

转】因为贱&#xff0c;所以生活艰辛&#xff01;告诉你们真相&#xff0c;你们会更绝望 我知道论坛里什么人都有&#xff0c;很多唱空的不代表就是空军&#xff0c;很可能是多军雇佣过来的卧底&#xff0c;故意挑起事端唱双簧戏的。同理&#xff0c;论坛上那些貌似多军的&…

趣图:这种贱贱的骚操作,你们试过么?

&#xff08;点击上方公众号&#xff0c;可快速关注&#xff09; 这种贱贱的骚操作&#xff0c;你试过么&#xff1f;用 IE6 VM 去 ping 竞争对手的网站 ↓↓↓ 关注「程序员的那些事」 每天看 IT 趣图 ↓↓↓

我为什么这么贱!

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;我贱的我&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我是神经…

真他妈的贱!

现在网络上的某些所谓的“黑客”根本不懂什么网络原理&#xff0c;更别说什么通讯协议了&#xff0c;整天只会利用别人研究出来的成果四处捣乱&#xff0c;真不知道他们的时间怎么会那么多&#xff01;

人就是贱啊!

中午时接到通知 让本人在接下来的两周内做一个J2ME的应用 听到这个消息 兴奋了一小下 呵 为什么 想想也是很久以前看过J2ME方面的东西 但没有真正的做过什么 而且已经有很长时间没有从事真正的开发了 一直不是这样或那样的闲事 不过更多的时间都是闲着 虽然闲着也不…

提高养号测评的安全性:详解浏览器指纹追踪技术及其防范措施

网络指纹追踪的存在使得每次在浏览网页&#xff0c;甚至是在“无痕浏览”模式下&#xff0c;都会留下痕迹。无论有多么“机智”&#xff0c;只要浏览过某些网站&#xff0c;那么就会在网络上留下“指纹”。这是因为大部分网页都会嵌入一些追踪代码&#xff0c;这些代码会收集用…

4、建造者模式

一、创建型模式 4、建造者模式 (1)、概述 将一个复杂的对象的构建与它的表示分离&#xff0c;是的同样的构建过程可以创建不同的表示。为了灵活构造复杂对象&#xff0c;该对象会有多个成员变量&#xff0c;在外部调用的时候&#xff0c;不需要或者不方便一次性创建出所有的成员…

程序物语(三):做人、做事、生活

最近有些忙&#xff0c;真正的没有价值的瞎忙。再挤出点时间&#xff0c;理了下思绪&#xff0c;继续一下。 开始之前&#xff0c;我想说明一下&#xff0c;前两篇文章&#xff0c;是想说一些教训和经验&#xff0c;大家尽量结合自己的实际&#xff0c;不建议去模仿&#xff…