LeetCode 回溯算法(代码随想录笔记,个人记录用)

216 组合总和Ⅲ

class Solution {
public:
    vector<vector<int>> res;
    vector<int> group;
    int Sum=0;

    void func(int k,int n,int start)
    {
        if(Sum>n)return;
        
        if(group.size()==k)
        {
            if(Sum==n) res.push_back(group);
            return;
        }    

        for(int i=start;i<=9-(k-group.size())+1;++i)
        {
            Sum+=i;
            group.push_back(i);
            
            func(k,n,i+1);

            Sum-=group.back();
            group.pop_back();
        }
    }

    vector<vector<int>> combinationSum3(int k, int n) {
        res.clear();
        group.clear();
        func(k,n,1);
        return res;
    }
};

17 电话号码的字母组合

class Solution {
public:
    const string Str[11]=
    {
        "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz",""
    };


    vector<string> res;
    string piece;

    int index=0; //len=edigits.size()时匹配一次完成

    void func(string str,int index) //str 数字
    {
        if(index==str.size())
        {
            res.push_back(piece);
            return;
        }

        int digit=str[index]-'0';
        string substr=Str[digit];
        for(auto elem:substr)
        {
            piece.push_back(elem);
            func(str,index+1);
            piece.pop_back();
           // --index;
        }
    }

    vector<string> letterCombinations(string digits) {
        string edigits;
        for(auto elem:digits)
        {
            if(elem=='2'||elem=='3'||elem=='4'||elem=='5'||elem=='6'||elem=='7'||elem=='8'||elem=='9')
            {
                edigits.push_back(elem);
            }
        }

        //edigits 有效数字2~9
        res.clear();
        piece.clear();
        if(edigits.size()==0) return res;

        func(edigits,0);
        
        return res;
    }
};

39 组合总和

class Solution {
public:

    vector<vector<int>> res;
    vector<int> group;
    int Sum=0;

    void func(vector<int>& nums,int& target)
    {
        if(Sum>=target)
        {
            if(Sum==target)res.push_back(group);

            // Sum-=nums[i];
            // group.pop_back();
            return;
        }

        for(int i=0;i<nums.size();++i)
        {
            if(group.size()==0 || (group.size()>=1 && nums[i]>=group.back() ) )
            {
                Sum+=nums[i];
                group.push_back(nums[i]);

                func(nums,target);
                Sum-=nums[i];
                group.pop_back();
            }
           
        }
    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {

        sort(candidates.begin(),candidates.end());//递增序列
        res.clear();
        group.clear();
        func(candidates,target);
        return res;
    }
};

40 组合总和Ⅱ

class Solution {
public:
    vector<vector<int>> res;
    vector<int> group;
    int Sum;

    void func(vector<int>& candidates,int target,int index,vector<bool>& bUsed)
    {
        if(Sum>=target)
        {
            if(Sum==target) res.push_back(group);
            return;
        }

        for(int i=index;i<candidates.size();++i)
        {
            if(i>0 && (candidates[i]==candidates[i-1]&&bUsed[i-1]==false) ) continue;

            Sum+=candidates[i];
            group.push_back(candidates[i]);
            bUsed[i]=true;
            func(candidates,target,i+1,bUsed);
            Sum-=candidates[i];
            group.pop_back();
            bUsed[i]=false;
        }
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        res.clear();
        group.clear();
        vector<bool> bUsed(candidates.size(),false);

        func(candidates,target,0,bUsed);
        return res;
    }
};

131 分割回文串

class Solution {
public:
    vector<vector<string>> res;
    vector<string> group;

    bool IsStr(string str)
    {
        int i=0,j=str.size()-1;
        while(i<=j)
        {
            if(str[i]!=str[j]) return false;
            ++i;
            --j;
        }

        return true;
    }

    void func(string s,int index)
    {
        if(index>=s.size()) 
        {
            res.push_back(group);
            return;
        }

        for(int i=index;i<s.size();++i)
        {
            if(IsStr(s.substr(index,i-index+1))) group.push_back(s.substr(index,i-index+1));
            else continue;

            func(s,i+1);
            
            group.pop_back();
        }
    }

    vector<vector<string>> partition(string s) {
        res.clear();
        group.clear();
        func(s,0);
        return res;
    }
};

93 复原IP地址

class Solution {
public:
    vector<string> res;
    vector<string> ip;

    bool UnitCheck(string str)
    {
        if(str[0]=='0'&&str.size()>1) return false;

        int a=atoi(str.c_str());
        if(a<0||a>255) return false;

        return true;
    }

    string ProcessIp(vector<string> ip)
    {
        string str;
        str+=ip[0];str+=".";
        str+=ip[1];str+=".";
        str+=ip[2];str+=".";
        str+=ip[3];

        return str;
    }

    void func(string s,int index)
    {
        if(ip.size()==4
        &&ip[0].size()+ip[1].size()+ip[2].size()+ip[3].size()==s.size())
        {
            string str=ProcessIp(ip);
            res.push_back(str);
            return;
        }

        for(int i=index;i<s.size();++i)
        {
            if(UnitCheck(s.substr(index,i-index+1)))
            {
                ip.push_back(s.substr(index,i-index+1));
            }
            else
            {
                continue;
            }

            func(s,i+1);
            ip.pop_back();
            
        }
    }

    vector<string> restoreIpAddresses(string s) {
        res.clear();
        ip.clear();
        func(s,0);
        return res;
    }
};

78 子集

class Solution {
public:
    vector<vector<int>> res;
    vector<int> group;

    void func(vector<int>& nums,int iStart)
    {
        res.push_back(group);
        if(iStart==nums.size())
        {
            return;
        }

        for(int i=iStart;i<nums.size();++i)
        {
            group.push_back(nums[i]);
            func(nums,i+1);
            group.pop_back();
        }
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        res.clear();
        group.clear();
        sort(nums.begin(),nums.end());
        func(nums,0);
        //res.push_back(vector<int>{});
        return res;
    }
};

90 子集Ⅱ

class Solution {
public:
    
    vector<vector<int>> res;
    vector<int> group;
    

    void func(vector<int>& nums,vector<bool>& bVisited,int iStart)
    {
        res.push_back(group);
        for(int i=iStart;i<nums.size();++i)
        {
            if(i>0&&nums[i]==nums[i-1]&&bVisited[i-1]==false) continue;
//[i-1]曾作为叶子节点回溯后等值曾作为上层节点,所以同层不必再从此往下取值
           
            group.push_back(nums[i]);
            bVisited[i]=true;

            func(nums,bVisited,i+1);

            bVisited[i]=false;
            group.pop_back();
        }
    }

    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        vector<bool> bVisited(nums.size(),false);
        sort(nums.begin(),nums.end());

        //for(auto elem:nums) cout<<elem<<" ";

        res.clear();
        group.clear();
        func(nums,bVisited,0);

        return res;

    }
};

46 全排列

class Solution {
public:
    
    vector<vector<int>> res;
    vector<int> group;

    void fun(vector<int>& nums,vector<bool>& bVisited)
    {
        if(group.size()==nums.size())
        {
            res.push_back(group);
            return;
        }
        

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

            group.push_back(nums[i]);
            bVisited[i]=true;

            fun(nums,bVisited);

            bVisited[i]=false;
            group.pop_back();
        }
    }

    vector<vector<int>> permute(vector<int>& nums) {
        res.clear();
        group.clear();
        vector<bool> bVisited(nums.size(),false);
        fun(nums,bVisited);
        
        return res;
    } 
};

对递归的过程可以在纸上画一画,clam down and  follow the process , you would figure it out!

47 全排列Ⅱ

class Solution {
public:
    
    vector<vector<int>> res;
    vector<int> group;

    void func(vector<int>& nums,vector<bool>& bVisited)
    {
        if(group.size()==nums.size()) {
            res.push_back(group);
            return;
        }

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

            if(i>0&&nums[i]==nums[i-1]&&bVisited[i-1]==false) continue;

//bVisited[i-1]==true也能通过?

//《代码随想录》 树枝去重与树层去重
//[1.1.2] [0]-[1]->continue;
//[1]-[0]-[2] push_bacK(group);

            group.push_back(nums[i]);
            bVisited[i]=true;

            func(nums,bVisited);

            group.pop_back();
            bVisited[i]=false;
        }
    }


    vector<vector<int>> permuteUnique(vector<int>& nums) {
        res.clear();
        group.clear();
        sort(nums.begin(),nums.end());

        vector<bool> bVisited(nums.size(),false);
        func(nums,bVisited);
        return res;
    }
};

51 N皇后问题

class Solution {
public:

    vector<vector<string>> res;
    vector<string> sol;

    void InitChessBoard(vector<string>& sol,int n)
    {
        string row;
        for(int i=0;i<n;++i) row.push_back('.');
        for(int i=0;i<n;++i) sol.push_back(row); 
    }

    void Place(vector<string>& sol,vector<vector<bool>>& bFull,int i,int j,int n)
    {
        sol[i][j]='Q';
        bFull[0][i]=true;
        bFull[1][j]=true;
        bFull[2][(i+j)]=true;
        bFull[3][(i-j+n-1)]=true;
    }

    void Remove(vector<string>& sol,vector<vector<bool>>& bFull,int i,int j,int n)
    {
        sol[i][j]='.';
        bFull[0][i]=false;
        bFull[1][j]=false;
        bFull[2][(i+j)]=false;
        bFull[3][(i-j+n-1)]=false;
    }
    
    bool Check(vector<vector<bool>>& bFull,int i,int j,int n)
    {
        if(bFull[0][i]==true) return false;//行
        if(bFull[1][j]==true) return false;//列
        if(bFull[2][(i+j)]==true) return false;//正斜 /
        if(bFull[3][(i-j+n-1)]==true) return false;//反斜 
        return true;
    }

    void func(vector<string>& sol,int n,int iRow,vector<vector<bool>>& bFull)
    {
        // cout<<"hello"<<endl;
        // for(auto elem:sol)
        // {
        //     cout<<elem<<endl;
        // }
        // for(auto row:bFull)
        // {
        //     for(auto elem:row)
        //     {
        //         cout<<elem<<" ";
        //     }
        //     cout<<endl;
        // }

        if(iRow==n)
        {
            res.push_back(sol);
            return;
        }

        for(int i=0;i<n;++i) //各列
        {
            
            if(Check(bFull,iRow,i,n)){
                Place(sol,bFull,iRow,i,n);
                func(sol,n,iRow+1,bFull);
                Remove(sol,bFull,iRow,i,n);
            }

        }
        //如果这行填过就到下一行
        if(sol[iRow][n-1]=='Q')
        {
            func(sol,n,iRow+1,bFull);
        }
    }

    vector<vector<string>> solveNQueens(int n) {
        
        res.clear();
        sol.clear();

        InitChessBoard(sol,n);//[0]行, [1]-[n]行的[0]列为棋盘边界
        
        vector<bool> bPlaced1(n,false);
        vector<bool> bPlaced2(2*n-1,false);
        vector<vector<bool>> bFull;

        for(int i=0;i<2;++i) bFull.push_back(bPlaced1);//行、列
        //正斜\反斜
        for(int i=2;i<4;++i) bFull.push_back(bPlaced2);


        func(sol,n,0,bFull);

        return res;


    }
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值