【LeetCode】递归回溯相关问题汇总

递归回溯相关问题汇总

树形问题

17. 电话号码的字母组合

题目描述

在这里插入图片描述

题解1 使用vector储存临时结果

class Solution {
    vector<string> ret;//返回值
    string s[10]={
        " "," ",
        "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
    };
public:

    void dfs(string digits,int index,string tmp)
    {
        if(index==digits.size())//结束条件
        {
            ret.push_back(tmp);
            return ;
        }
        //int num=int(digits[index]);
        string keyboard=s[digits[index]-'0'];
        cout<<keyboard;
        for(int i=0;i<keyboard.size();i++)
        {
            dfs(digits,index+1,tmp+keyboard[i]);//之前的字符串+当前char变量
        }
        return;
    }
    vector<string> letterCombinations(string digits) {
        if(digits.length()==0)return ret;
        dfs(digits,0,"");
        return ret;
    }
};

93. 复原IP地址

题目描述

在这里插入图片描述

题解1 回溯+剪枝

class Solution {
    vector<string> ret;
    vector<string> tmp;
    bool isvaild(string p)
    {
        int val=atoi(p.c_str());
        if(val>255||(p.size() >= 2 &&p[0]=='0'))return false;
        return true;

    }
public:
    void dfs(string s ,int pos)
    {
      int maxlen=(4-tmp.size())*3;//剩下部分的最长长度
            if(s.size()-pos>maxlen)//大于最长长度
                return;
        if(tmp.size()==4)
        {
            if(pos!=s.size())return;
            string s="";
            for(int i=0;i<3;i++)
            {
                s+=(tmp[i]+".");
           }
           s+=(tmp[3]);
           ret.push_back(s);
           return;   
        }
        else{

            for(int i=pos;i<pos+3&&i<s.size();i++)
            {
                string stmp=s.substr(pos,i-pos+1);
               // cout<<stmp<<endl;
                if(!isvaild(stmp))continue;
                tmp.push_back(stmp);
                dfs(s,i+1);
                tmp.pop_back();
            }
        }
        return;
    }
    vector<string> restoreIpAddresses(string s) {
       
        dfs(s,0);
        return ret;
    }
};

131. 分割回文串

题目描述

在这里插入图片描述

题解1 遍历以每个字母为起点的所有可能

class Solution {
    vector<vector<string>>ret;
    vector<string> tmp;
    bool isvalid(const string& s)
    {
        int j=s.size()-1;
        int i=0;
        while(i<=j)
        {
            if(s[i++]!=s[j--])
            return false;
        }
        return true;
    }
        bool isvalid(const string& s,int i,int j)
    {
        if(i>=j)return true;
        if(s[i++]!=s[j--])return false;
        return isvalid(s,i,j);
       // return true;
    }
public:
    void dfs(const string& s,int pos)
    {
        if(pos==s.size())
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=pos;i<s.size();i++ )
        {
            //cout<<"pos="<<pos<<"i="<<i;
            //string sub=s.substr(pos,i-pos+1);//当前子字符串
            //cout<<"sub="<<sub<<endl;
            if(isvalid(s,pos,i))
            {tmp.push_back(s.substr(pos,i-pos+1));
            dfs(s,i+1);
            tmp.pop_back();}
        }
        return;
    }
    vector<vector<string>> partition(const string& s) {
        if(s.size()==0)return ret;
        dfs(s,0);
        return ret;
    }
};

排列问题

46. 全排列

题目描述

在这里插入图片描述

题解1 使用visited记录之前是否使用过该元素

class Solution {    
    vector<bool> visited;
    vector<vector<int>> ret;
    void dfs(vector<int>& nums,vector<int>& tmp,int index)
    {
        if(index==nums.size())
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=0;i<nums.size();i++)
        {
            if(!visited[i])
            {
                tmp.push_back(nums[i]);
                visited[i]=true;
                dfs(nums,tmp,index+1);
                tmp.pop_back();
                visited[i]=false;
            }
        }
        return ;
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        visited=vector<bool>(nums.size());
        vector<int> tmp;
        dfs(nums,tmp,0);
        return ret;
    }
};

47 全排列Ⅱ

题目描述

在这里插入图片描述

题解1 使用map容器记录使用次数 每个位置只能使用一次该元素避免重复

    vector<vector<int>> ret;
    int size;
public:
    void dfs(unordered_map<int,int>& m,vector<int>&tmp)
    {
        if(tmp.size()==size)
        {
            ret.push_back(tmp);
            return ;
        }
        for(auto it : m)
        {
            //cout<<it.first<<" "<<it.second<<endl;
            if(it.second==0)continue;
            tmp.push_back(it.first);
            m[it.first]--;
            dfs(m,tmp);
            m[it.first]++;
            tmp.pop_back();
        }
        return;}
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if(nums.size()==0)return ret;
        unordered_map<int,int> m;
        size=nums.size();
        for(int i=0;i<nums.size();i++)
        {
            m[nums[i]]++;
        }
        /*for(auto it : m)
        {
            cout<<it.first<<" "<<it.second<<endl;
        }*/
        vector<int> tmp;
        dfs(m,tmp);
        return ret;
    }

题解2 使用vector排序 如果nums[i]==nums[i-1]就跳过

	    vector<vector<int>> ret;
    vector<bool> nums1;
    int size;
public:
    void dfs(vector<int>& nums,vector<int>&tmp)
    {
        if(tmp.size()==size)
        {
            ret.push_back(tmp);
            return ;
        }
        for(int i=0;i<size;i++)
        {
            if((nums1[i]==true)||(i>0&&nums[i]==nums[i-1]&&nums1[i-1]==false))continue;
            tmp.push_back(nums[i]);
            nums1[i]=true;
            dfs(nums,tmp);
            nums1[i]=false;
            tmp.pop_back();
        }
        return;}
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if(nums.size()==0)return ret;
        nums1.resize(nums.size());
        size=nums.size();
        sort(nums.begin(),nums.end());
        vector<int> tmp;
        dfs(nums,tmp);
        return ret;
    }

组合问题及优化

77. 组合

题目描述

在这里插入图片描述

题解1 回溯

    vector<vector<int>>ret;
    void dfs(int n,int k,vector<int>&tmp,int index)
    {
        if(tmp.size()==k)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<=n;i++)
        {
            //cout<<"index="<<index<<"i="<<i<<endl;
            tmp.push_back(i);
            dfs(n,k,tmp,i+1);
            tmp.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> combine(int n, int k) {
        vector<int>tmp;
        if(n<0||k<0||n<k)return ret;
        dfs(n,k,tmp,1);
        return ret;
    }

题解2 剪枝提前终止递归 i<=n-(k-tmp.size())+1

    vector<vector<int>>ret;
    void dfs(int n,int k,vector<int>&tmp,int index)
    {
        if(tmp.size()==k)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<=n-(k-tmp.size())+1;i++)//减枝 剩余还需要选k-tmp.size()个数字,所以i最大为K-M+1
        {
            //cout<<"index="<<index<<"i="<<i<<endl;
            tmp.push_back(i);
            dfs(n,k,tmp,i+1);
            tmp.pop_back();
        }
        return;
    }

39. 组合总和

题目描述

在这里插入图片描述

题解1 组合型问题不能从i=0开始 要从i=index+1

    vector<vector<int>> ret;
    vector<int> tmp;

    void dfs(vector<int>& candidates, int target,int index)
    {
        if(target==0)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<candidates.size();i++)
        {
            if(candidates[i]>target)continue;
            tmp.push_back(candidates[i]);
            dfs(candidates,target-candidates[i],i);
            tmp.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        if(candidates.size()==0)
        {
            return ret;
        }
        dfs(candidates,target,0);
        return ret;
    }

题解2 优化 先排序就可以提前终止递归

class Solution {
    vector<vector<int>> ret;
    vector<int> tmp;

    void dfs(vector<int>& candidates, int target,int index)
    {
        if(target==0)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<candidates.size();i++)
        {
            if(candidates[i]>target)break;
            tmp.push_back(candidates[i]);
            dfs(candidates,target-candidates[i],i);
            tmp.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        
        if(candidates.size()==0)
        {
            return ret;
        }
        sort(candidates.begin(),candidates.end());
        dfs(candidates,target,0);
        return ret;
    }
};

40. 组合总和 II

题目描述

在这里插入图片描述

题解1 candidates[i]==candidates[i-1]排序去除

    vector<vector<int>> ret;
   
    vector<int>tmp;
    void dfs(vector<int>& candidates, int target,int index,vector<int>&tmp)
    {
        //vector<bool> isused;
        //isused.resize(candidates.size());
        if(target==0)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<candidates.size();i++)
        {
            cout<<"index="<<index<<"i="<<i<<endl;
            if(candidates[i]>target)break;
            if( i>index&&candidates[i]==candidates[i-1])
            {//isused[i]=true;
            continue;}
            tmp.push_back(candidates[i]);
            //isused[i]=true;
            dfs(candidates,target-candidates[i],i+1,tmp);
            //isused[i]=false;
            tmp.pop_back();
            
        }
        return;
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        if(candidates.size()==0)return ret;
        
        sort(candidates.begin(),candidates.end());
        for(auto i:candidates)
        {
         //   cout<<i<<endl;
        }
        dfs(candidates,target,0,tmp);
        return ret;
    }

题解2 通过bool数组去除

class Solution {
    vector<vector<int>> ret;
   
    vector<int>tmp;
    void dfs(vector<int>& candidates, int target,int index)
    {
        vector<bool> isused;
         isused.resize(candidates.size());
        if(target==0)
        {
            ret.push_back(tmp);
            return;
        }
        for(int i=index;i<candidates.size();i++)
        {
            cout<<"index="<<index<<"i="<<i<<endl;
            if(candidates[i]>target)break;
            if(isused[i]||( i>0&&candidates[i]==candidates[i-1]&&isused[i-1]))//上一个元素用过了
            {isused[i]=true;
            continue;}
            tmp.push_back(candidates[i]);
            isused[i]=true;
            dfs(candidates,target-candidates[i],i+1);
            //isused[i]=false;
            tmp.pop_back();
            
        }
        return;
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        if(candidates.size()==0)return ret;
        
        sort(candidates.begin(),candidates.end());
        for(auto i:candidates)
        {
         //   cout<<i<<endl;
        }
        dfs(candidates,target,0);
        return ret;
    }
};

216. 组合总和 III

题目描述

在这里插入图片描述

题解1

class Solution {
    vector<vector<int>> ret;
    vector<int> tmp;
    // k为几个数 n为和
    void dfs(int k,int n,int index)
    {
        if(tmp.size()==k)
        {
            if(n==0)
            ret.push_back(tmp);
            return ;
        }
        for(int i=index;i<=9;i++)
        {
            if(i>n||9*k<n)break; //提前终止
            //if()
            //cout<<"index="<<index<<" i="<<i<<endl;
            tmp.push_back(i);
            dfs(k,n-i,i+1);
            tmp.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        if(n<1||k<1||k>n)return ret;
        dfs(k,n,1);
        return ret;
    }
};

题解二 提前终止优化

class Solution {
    vector<vector<int>> ret;
    vector<int> tmp;
    void dfs(int k,int n,int index)
    {
        if(tmp.size()==k)
        {
            if(n==0)
            ret.push_back(tmp);
            return ;
        }
        for(int i=index;i<=9;i++)
        {
            if(i>n||9*(k-tmp.size())<n)break; ///优化
            //if()
            //cout<<"index="<<index<<" i="<<i<<endl;
            tmp.push_back(i);
            dfs(k,n-i,i+1);
            tmp.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        if(n<1||k<1||k>n)return ret;
        dfs(k,n,1);
        return ret;
    }
};

78. 子集

题目描述

在这里插入图片描述

题解1 正常回溯

class Solution {
    vector<vector<int>> ret;
    vector<int> tmp;
    void dfs(vector<int>& nums,int index){
        ret.push_back(tmp);
        for(int i=index;i<nums.size();i++)
        {
            tmp.push_back(nums[i]);
            dfs(nums,i+1);
            tmp.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        if(nums.size()==0)return ret;
        dfs(nums,0);
        return ret;
    }
};

题解2 使用数组循环

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        //特判
        if(nums.size()==0)return {{}};
        vector<vector<int>> ans;
        ans.push_back({});
        //当前新加入的值nums[i]
        for(int i=0;i<nums.size();i++)
        {
            int tmpsize=ans.size();
            for(int j=0;j<tmpsize;j++)
            {
                vector<int>tmp=ans[j];
                tmp.push_back(nums[i]);
                ans.push_back(tmp);}
        }
        return ans;
    }
};
//输出
0 1 2 12 3 13 23 123

1 

1 
2 
1 2 

90. 子集 II

题目描述

在这里插入图片描述

题解1

class Solution {
    vector<vector<int>> ret;
    vector<int> tmp;
    void dfs(vector<int>& nums,int index)
    {
        ret.push_back(tmp);
        for(int i=index;i<nums.size();i++)
        {
            if(i>index&&nums[i]==nums[i-1])continue;//去重
            tmp.push_back(nums[i]);
            dfs(nums,i+1);
            tmp.pop_back();
        }
        return ;
    }
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());//排序
        dfs(nums,0);
        return ret;
    }
};

题解2 位运算 看不懂

class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
	sort(nums.begin(), nums.end());
	int S = nums.size();
	int N = 1 << S;//二进制数
    cout<<N<<endl;
	vector<vector<int> > res;
	for (int i = 0; i < N; ++i) {
		vector<int> v;
		bool flag = true;
		for (int j = 0; j < S; ++j)
		{
			if (i & (1 << j))//取每一位:不需要声明为二进制,这样就可以!! 
			{
                cout<<"i="<<i<<" j="<<j<<endl;
				if (j != 0 && nums[j] == nums[j - 1] && ((i&(1 << (j - 1))) == 0))//除重
				{
					flag = false;
					break;
				}	
				v.push_back(nums[j]);
			}
		}
		if(flag)
			res.push_back(v);
	}
	return res;
}
};

401. 二进制手表

题目描述

在这里插入图片描述

题解1 逆向思维 求整数里有多少个1

class Solution {
    int count1(int t)
    {
        int ret=0;
        while(t)
        {
            t=t&(t-1);
            ret++;
        }
        return ret;
    }
public:
    vector<string> readBinaryWatch(int num) {
        vector<string> ret;
        for(int i=0;i<12;i++)
        {
            for(int j=0;j<60;j++)
            {
                if(count1(i)+count1(j)==num)
                {
                    string tmp=j>9?to_string(i)+":"+to_string(j):to_string(i)+":0"+to_string(j);
                    ret.push_back(tmp);
                }
            }
        }
        return ret;
    }
};

题解2 正常回溯

class Solution {
public:
vector<string> ans;
vector<string> readBinaryWatch(int num) {
    DFS(num, 0, vector<int>(10));
    return ans;
}
void DFS(int num, int pos, vector<int>time) {
    if (num == 0) {
        int hour = time[0] + 2 * time[1] + 4 * time[2] + 8 * time[3];
        int minute = time[4] + 2 * time[5] + 4 * time[6] + 8 * time[7] + 16 * time[8] + 32 * time[9];
        if (hour < 12 && minute < 60) {
            char buffer[6];
            sprintf(buffer, "%d:%.2d", hour, minute);
            ans.push_back(buffer);
        }
        return;
    }
    for (int i = pos; i <= 10 - num; i++) {//i为第一个灯亮的位置
        time[i]++;
        DFS(num-1, i + 1, time);
        time[i]--;
    }
}

};

二维回溯

79. 单词搜索

题目描述

在这里插入图片描述

题解1

class Solution {

private:
    int d[4][2] = {{-1, 0}, {0,1}, {1, 0}, {0, -1}};
    int m, n;
    vector<vector<bool>> visited;

    bool inArea(int x, int y){
        return x >= 0 && x < m && y >= 0 && y < n;
    }

    // 从board[startx][starty]开始, 寻找word[index...word.size())
    bool searchWord(const vector<vector<char>> &board, const string& word, int index,
                    int startx, int starty ){

        //assert(inArea(startx,starty));
        if(index == word.size() - 1)
            return board[startx][starty] == word[index];

        if(board[startx][starty] == word[index]){
            visited[startx][starty] = true;
            // 从startx, starty出发,向四个方向寻
            for(int i = 0 ; i < 4 ; i ++){
                int newx = startx + d[i][0];
                int newy = starty + d[i][1];
                if(inArea(newx, newy) && !visited[newx][newy] &&
                   searchWord(board, word, index + 1, newx, newy))
                    return true;
            }
            visited[startx][starty] = false;
        }
        return false;
    }

public:
    bool exist(vector<vector<char>>& board, string word) {

        m = board.size();
        assert(m > 0);
        n = board[0].size();
        assert(n > 0);

        visited.clear();
        for(int i = 0 ; i < m ; i ++)
            visited.push_back(vector<bool>(n, false));

        for(int i = 0 ; i < board.size() ; i ++)
            for(int j = 0 ; j < board[i].size() ; j ++)
                if(searchWord(board, word, 0, i, j))
                    return true;

        return false;
    }
};

200. 岛屿数量

题目描述

在这里插入图片描述

题解1 判断是否访问过

class Solution {
    int d[4][2] = {{-1, 0}, {0,1}, {1, 0}, {0, -1}};
    int m, n;
    bool isvalid(int x,int y)
    {
        return x>=0&&x<m&&y>=0&&y<n;
    }
    vector<vector<bool>> visited;
    void dfs(vector<vector<char>>& grid,int x,int y)
    {
        visited[x][y]=true;
        for(int i=0;i<4;i++)
        {
            int newx=x+d[i][0];
            int newy=y+d[i][1];
            //cout<<newx<<" "<<newy<<endl;
            if(isvalid(newx,newy)&&grid[newx][newy]=='1'&&!visited[newx][newy])
            dfs(grid,newx,newy);
        }
    }
public:
    int numIslands(vector<vector<char>>& grid) {
        m=grid.size();
        if(m==0)return 0;
        n=grid[0].size();
        visited=vector<vector<bool>>(m,vector<bool>(n,false));
        int count=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(isvalid(i,j)&&grid[i][j]=='1'&&!visited[i][j])
                {
                    dfs(grid,i,j);
                    count++;
                }
            }
        }
        return count;
    }
};

题解2 不使用遍历记录访问情况 原地记录

//===========岛屿2
class Solution {
    int d[4][2] = {{-1, 0}, {0,1}, {1, 0}, {0, -1}};
    int m, n;
    bool isvalid(int x,int y)
    {
        return x>=0&&x<m&&y>=0&&y<n;
    }
    
    void dfs(vector<vector<char>>& grid,int x,int y)
    {
        grid[x][y]='0';
        for(int i=0;i<4;i++)
        {
            int newx=x+d[i][0];
            int newy=y+d[i][1];
            //cout<<newx<<" "<<newy<<endl;
            if(isvalid(newx,newy)&&grid[newx][newy]=='1')
            dfs(grid,newx,newy);
        }
    }
public:
    int numIslands(vector<vector<char>>& grid) {
        m=grid.size();
        if(m==0)return 0;
        n=grid[0].size();
        
        int count=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(isvalid(i,j)&&grid[i][j]=='1')
                {
                    dfs(grid,i,j);
                    count++;
                }
            }
        }
        return count;
    }
};

130. 被围绕的区域

题目描述

在这里插入图片描述

题解 先反转边上的

class Solution {
    int m,n;
    bool isvalid(int x,int y)
    {
        //cout<<m<<n<<endl;
        return x>=0&&x<m&&y>=0&&y<n;
    }
    bool isedge(int x,int y)
    {
        return x==0||y==0||x==m-1||y==n-1;
    }
    int step[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
    void dfs(vector<vector<char>>& board,int x,int y)
    {
        //cout<<"111"<<endl;
        board[x][y]='Y';
        //cout<<"111"<<endl;
        for(int i=0;i<4;i++)
        {
            int newx=x+step[i][0];
            int newy=y+step[i][1];
            if(isvalid(newx,newy)&&board[newx][newy]=='O')
            {
                //cout<<"222"<<endl;
                dfs(board,newx,newy);
            }
        }
    }
public:
    void solve(vector<vector<char>>& board) {
        m=board.size();
        if(m==0)return;
        n=board[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(isedge(i,j)&&board[i][j]=='O')
                dfs(board,i,j);
            }
        }
       // cout<<"111"<<endl;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(board[i][j]=='O')board[i][j]='X';
                else if(board[i][j]=='Y')board[i][j]='O';
            }
        }
        return;
    }
};

417. 太平洋大西洋水流问题

题目描述

在这里插入图片描述

题解 两次dfs深度搜索 从边缘到中心

class Solution {
    int m,n;
    int step[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
    vector<vector<bool>> palne;
    vector<vector<bool>> west;
    bool isvalid(int x,int y)
    {
        //cout<<m<<n<<endl;
        return x>=0&&x<m&&y>=0&&y<n;
    }
    bool isplane(int x,int y)
    {
        return x==0||y==0;
    }
     bool iswest(int x,int y)
    {
        return x==m-1||y==n-1;
    }

    void dfs(vector<vector<int>>& matrix,vector<vector<bool>>& palne2,int x,int y)
    {
        
        palne2[x][y]=true;
        //cout<<"plane x="<<x<<" y="<<y<<endl;
        for(int i=0;i<4;i++)
        {
            int newx=x+step[i][0];
            int newy=y+step[i][1];
            //cout<<"x="<<x<<" y="<<y<<endl;
            if(isvalid(newx,newy)&&matrix[newx][newy]>=matrix[x][y]&&!palne2[newx][newy])
            {
                dfs(matrix,palne2,newx,newy);
            }
        }
    }
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
        vector<vector<int >> ret;
        
        m=matrix.size();
        if(m==0)return ret;
        n=matrix[0].size();
        palne=vector<vector<bool>>(m,vector<bool>(n,false));
        west=vector<vector<bool>>(m,vector<bool>(n,false));
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(iswest(i,j))
                {
                    //cout<<'1'<<endl;
                    dfs(matrix,west,i,j);
                }
                if(isplane(i,j))
                {
                    dfs(matrix,palne,i,j);
                }
            }
        }
        //cout<<'s'<<endl;;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(palne[i][j]==true&&west[i][j]==true)
                {
                    vector<int> tmp;
                    tmp.push_back(i);
                    tmp.push_back(j);
                    ret.push_back(tmp);
                }
            }
        }
        return ret;

    }
};

51. N皇后

题目描述

在这里插入图片描述

题解

class Solution {
    vector<vector<string>> ret;
    vector<bool> ver;
    vector<bool> rigth;
    vector<bool> left;
    void tostring(vector<int>&tmp)
    {
        //string tmp1=string(n,.);
        vector<string> tmpret=vector<string>(tmp.size(),string(tmp.size(),'.'));
        for(int i=0;i<tmp.size();i++)
        {
            tmpret[i][tmp[i]]='Q';
        }
        ret.push_back(tmpret);
    }
    void put(vector<int>&tmp,int n,int index)
    {
        if(index==n)
        {
            tostring(tmp);
            return;
        }
        for(int i=0;i<n;i++)
        {
            if(!ver[i]&&!rigth[index+i]&&!left[index-i+n-1])
            {
                ver[i]=true;
                rigth[index+i]=true;
                left[index-i+n-1]=true;
                tmp.push_back(i);
                put(tmp,n,index+1);
                ver[i]=false;
                rigth[index+i]=false;
                left[index-i+n-1]=false;
                tmp.pop_back();
            }
        }
        return;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
        if(n==0)return ret;
        vector<int> tmp;
        ver=vector<bool>(n,false);
        rigth=vector<bool>(2*n-1,false);
        left=vector<bool>(2*n-1,false);
        put(tmp,n,0);
        return ret;
    }
};

37. 解数独

题目描述

在这里插入图片描述

题解

class Solution {
public:
    int row[9][9] = {0};
    int col[9][9] = {0};
    int l[9][9] = {0};
    void solveSudoku(vector<vector<char>>& board) {
        for(int i=0;i<9;++i){
            for(int j=0;j<9;++j){
                if(board[i][j]!='.'){
                    row[i][board[i][j]-'1'] = 1;
                    col[j][board[i][j]-'1'] = 1;
                    l[i/3*3+j/3][board[i][j]-'1'] = 1;
                }
            }
        }
        backtrack(board,0,0);
    }

    bool backtrack(vector<vector<char>>& board,int r,int c){
        //递归边界
        if(r>8) return true;
        if(board[r][c]=='.'){
            for(char ch='1';ch<='9';++ch){
                //符合要求
                if(row[r][ch-'1']==1||col[c][ch-'1']==1||l[r/3*3+c/3][ch-'1']==1) continue;
                board[r][c] = ch;
                row[r][ch-'1'] = 1;
                col[c][ch-'1'] = 1;
                l[r/3*3+c/3][ch-'1'] = 1;

                //只需找到一个解即可
                if(backtrack(board,r+(c+1)/9,(c+1)%9)) return true;

                //回溯
                board[r][c] = '.';
                row[r][ch-'1'] = 0;
                col[c][ch-'1'] = 0;
                l[r/3*3+c/3][ch-'1'] = 0;
            }
        }
        else return backtrack(board,r+(c+1)/9,(c+1)%9);

        //对空格处操作:没有得到合适的解就会跳到此处 
        return false;
    }
};··	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值