代码随想录——回溯习题合集

77. 组合

 vector<vector<int>> res;
    vector<vector<int>> combine(int n, int k) {
        vector<int> ans;
         xx(0,n,k,1,ans);
        return res;
    }
    void xx(int m,int n,int k,int js,vector<int>& ans){
        if(m==k)    res.push_back(ans);
        for(int i=js;i<=n;i++){
            ans.push_back(i);
            xx(m+1,n,k,i+1,ans);
            ans.pop_back();
        }
    }

 216. 组合总和 III

 

vector<vector<int>> res;
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<int> ans;
        xx(k,n,0,1,ans);
        return res;
    }   
    void xx(int k,int n,int sum,int index,vector<int>& ans){
        if(ans.size()>k||sum>n) return;
        if(sum==n&&ans.size()==k) res.push_back(ans);
        for(int i=index;i<=9;i++){
            ans.push_back(i);
            xx(k,n,sum+i,i+1,ans);
            ans.pop_back();
        }
    }

 17. 电话号码的字母组合

 unordered_map<int,string>map;
    vector<string> res;
    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return res;
        map[2]="abc";map[3]="def";map[4]="ghi";map[5]="jkl";map[6]="mno";
        map[7]="pqrs";map[8]="tuv";map[9]="wxyz";
        vector<int> num;
        string str;
        for(int i=0;i<digits.size();i++) num.push_back(digits[i]-'0');
        xx(str,0,num);
        return res;
    }
    void xx(string str,int index,vector<int> num){
        if(str.size()>num.size()) return ;
        if(str.size()==num.size()) res.push_back(str);
        for(int i=index;i<num.size();i++){
            for(int j=0;j<map[num[i]].size();j++){
                str+=map[num[i]][j];
                xx(str,i+1,num);
                str.pop_back();
            }
        }
    }

 39. 组合总和

 vector<vector<int>> res;
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int>ans;
        xx(0,0,ans,candidates,target);
        return res;
    }
    void xx(int sum,int index,vector<int>ans, vector<int>& candidates,int target){
        if(sum>target) return;
        if(sum==target) res.push_back(ans);
        for(int i=index;i<candidates.size()&&sum<target;i++){
            sum+=candidates[i];
            ans.push_back(candidates[i]);
            xx(sum,i,ans,candidates,target);
            ans.pop_back();
            sum-=candidates[i];
        } 
    }

 40. 组合总和 II

vector<vector<int>> res;
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<int>ans;
        xx(0,0,ans,candidates,target);
      //  sort(res.begin(),res.end());
       // res.erase(unique(res.begin(),res.end()),res.end()) ;
        return res;
    }
    void  xx(int index,int sum,vector<int>& ans,vector<int> candidates,int target){
        if(sum>target) return ;
        if(sum==target) res.push_back(ans);
        
        for(int i=index;i<candidates.size()&&sum<target;i++){
            if(i!=index&&candidates[i]==candidates[i-1]) continue;
            sum+=candidates[i];
            ans.push_back(candidates[i]);
            xx(i+1,sum,ans,candidates,target);
            ans.pop_back();
            sum-=candidates[i];
        }
    }

 131. 分割回文串

 vector<vector<string>> res;
     vector<string>ans;
    vector<vector<string>> partition(string s) {
        xx(0,s);
        return res;
    }
    void xx(int index, string s){
        if(index>s.size()) return;
        
        for(int len=1;len+index<=s.size();len++){
            string str=s.substr(index,len);
            
            bool flag=true;
            for(int i=0;i<str.size()/2;i++) 
                if(str[i]!=str[str.size()-i-1]) flag=false;
            
            if(flag) ans.push_back(str);
            if(flag&&index+len==s.size()) res.push_back(ans); 

            if(flag) xx(index+len,s);
            if(flag) ans.pop_back();
        }
    }

 93. 复原 IP 地址

vector<string> res;
    string ans;
    vector<string> restoreIpAddresses(string s) {
        xx(0,s);
        return res;
    }
    void xx(int index,string s){
        if(count(ans.begin(),ans.end(),'.')>3) return;
        if(index>s.size()) return ;
        if(index==s.size()&&count(ans.begin(),ans.end(),'.')==3) res.push_back(ans);
        for(int len=1;index+len<=s.size();len++){
            string str=s.substr(index,len);

            if(str[0]=='0'&&str.size()>1) return ;
            if(atoi(str.c_str())>255) return ;

            string ori=ans;
            if(index+len!=s.size()) str+='.';
            ans+=str;
            xx(index+len,s);
            ans=ori;
        }
    }

 78. 子集

vector<vector<int>> res;
    vector<int> ans;
    vector<vector<int>> subsets(vector<int>& nums) {
        xx(0,nums);
        return res;
    }
    void xx(int index,vector<int>nums){
        if(index>nums.size()) return ;
        res.push_back(ans);
        for(int i=index;i<nums.size();i++){
            ans.push_back(nums[i]);
            xx(i+1,nums);
            ans.pop_back();
        }
    }

 90. 子集 IId

 第一种方法

vector<vector<int>>res;
    vector<int> ans;
    int st[11];
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        xx(0,nums);
        return res;
    }
    void xx(int index,vector<int> nums){
       if(index>nums.size()) return;
        if(index==nums.size()){
             res.push_back(ans);
             return;
        }
       
        int k=index+1;
        while(k<nums.size()&&nums[k]==nums[k-1]) k++;

        for(int i=0;i<=k-index;i++){
            xx(k,nums);
            ans.push_back(nums[index]);
        }
         for(int i=0;i<=k-index;i++){
            ans.pop_back();
        }
    }

第二种方法

 vector<vector<int>>res;
    vector<int> ans;
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        vector<bool> st(nums.size(),false);
        sort(nums.begin(),nums.end());
        xx(0,nums,st);
        return res;
    }
    void xx(int index,vector<int> nums,vector<bool>& st){
        if(index>nums.size()) return;
        res.push_back(ans);
         
        for(int i=index;i<nums.size();i++){
            if(i&&i<nums.size()&&nums[i]==nums[i-1]&&st[i-1]==false) continue;
            ans.push_back(nums[i]);
            st[i]=true;
            xx(i+1,nums,st);
            st[i]=false;
            ans.pop_back();
        }

    }

***491. 递增子序列***

 用unordered_set<int> uset来记录同一层有没有相同的使用情况

  vector<vector<int>> res;
    vector<int> ans;
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        vector<bool> st(nums.size(),false);
        xx(0,nums,st);

        return res;
    }
    void xx(int index,vector<int> nums,vector<bool>& st){
        if(index>=nums.size()) return;
        //if(index==nums.size()&&ans.size()>1) res.push_back(ans);
          
        unordered_set<int> uset;
        for(int i=index;i<nums.size();i++){
            if((i&&nums[i]==nums[i-1]&&!st[i-1])||(uset.find(nums[i])!=uset.end())) continue;
            if(ans.size()&&nums[i]<ans[ans.size()-1]) continue;
            ans.push_back(nums[i]);
            uset.insert(nums[i]);
            st[i]=true;
            if(ans.size()>1)  res.push_back(ans);
            
            xx(i+1,nums,st);
            ans.pop_back();
            st[i]=false;
        }
    }

 46. 全排列

  vector<vector<int>> res;
    vector<int> ans;
    vector<vector<int>> permute(vector<int>& nums) {
        vector<bool>st(nums.size(),false);
        xx(0,nums,st);
        return res;
    }
    void xx(int index,vector<int> nums,vector<bool>st){
        if(ans.size()==nums.size()){
            res.push_back(ans);
            return;
        } 

        for(int i=0;i<nums.size();i++){
           if(st[i]) continue;

            ans.push_back(nums[i]);
            st[i]=true;
            xx(i+1,nums,st);
            st[i]=false;
            ans.pop_back();
        }
    }

 47. 全排列 II

  vector<vector<int>> res;
    vector<int> ans;
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<bool> st(nums.size(),false);
        xx(nums,st);
        return res;
    }
    void xx(vector<int> nums,vector<bool>& st){
        if(ans.size()==nums.size()) {
            res.push_back(ans);
            return;
        }

        for(int i=0;i<nums.size();i++){
            if((i&&nums[i]==nums[i-1]&&!st[i-1])||st[i]) continue;
            ans.push_back(nums[i]);
            st[i]=true;
            xx(nums,st);
            st[i]=false;
            ans.pop_back();
        }
    }

 332. 重新安排行程

 unordered_map<string, multiset<string>> g;
    vector<string>ans;
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        for(auto cc: tickets) g[cc[0]].insert(cc[1]);
        dfs("JFK");
        reverse(ans.begin(),ans.end());
        return ans;
    }
    void dfs(string str){
        while(g[str].size()){
            string var = *g[str].begin();
            g[str].erase(g[str].begin());
            dfs(var);
        }
        ans.push_back(str);
    }

 51. N 皇后

 vector<vector<string>>  res;
    vector<vector<string>> solveNQueens(int n) {
        vector<string> ans(n, std::string(n, '.'));
        xx(0,n,ans);
        return res;
    }
    void xx(int h,int n,vector<string>& ans){
        if(h==n){
            res.push_back(ans);
            return ;
        }
        for(int i=0;i<n;i++){
            if(check(h,i,n,ans)){
                ans[h][i]='Q';
                xx(h+1,n,ans);
                ans[h][i]='.';
            }
        }
    }
    bool check(int h,int l,int n,vector<string> ans){
        bool flag=true;
        for(int i=0;i<h;i++) 
            if(ans[i][l]=='Q') flag=false;

        for(int i=1;h-i>=0&&l-i>=0;i++)
            if(ans[h-i][l-i]=='Q') flag=false;

        for(int i=1;h-i>=0&&l+i<n;i++)
            if(ans[h-i][l+i]=='Q') flag=false;
        
        return flag;
    }

 37. 解数独

 int num=0;
    void solveSudoku(vector<vector<char>>& board) {
        xx(board);
    }
    bool xx(vector<vector<char>>& board){
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board[0].size();j++){
                if(board[i][j]=='.'){
                    for(int k=1;k<=9;k++){
                        if(check(i,j,k,board)){
                            board[i][j]=k+'0';
                            if(xx(board)) return true;
                            board[i][j]='.';
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    bool check(int h,int l,int k,vector<vector<char>>& board){
        for(int i=0;i<9;i++)
            if(board[i][l]==(k+'0')) return false;
        
        for(int i=0;i<9;i++)
            if(board[h][i]==(k+'0')) return false;
        
        int startRow = (h / 3) * 3;
        int startCol = (l / 3) * 3;
        for (int i = startRow; i < startRow + 3; i++) { // 判断9方格里是否重复
            for (int j = startCol; j < startCol + 3; j++) {
                if (board[i][j] == k+'0' ) {
                    return false;
                }
            }
        }
       
        
        return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值