玩转算法面试:(七)递归和回溯法

回溯问题可以转化成树形问题

回溯法是暴力解法的一个主要手段

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

class Solution {
private:
    const string letterMap[8] ={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> ret;
public:
    //此时s中保存了digits[0,1,...,index-1]翻译到的字符串
    //寻找digits[index]匹配的字母,获得digits[0,1,...,index]翻译到的字符串
    void combination(const string &digits, int index, string s)
    {
        if(index == digits.size())
        {
            ret.push_back(s);
            return;
        }
        
        string letter = letterMap[digits[index] - '2'];
        for(int i = 0; i < letter.size(); i++)
        {
            combination(digits, index+1, s+letter[i]);
        }
        
        return;
    }
    vector<string> letterCombinations(string digits) {
        if(digits.size() == 0)
            return ret;
        combination(digits, 0, "");
        return ret;
    }
};

加入调试信息,查看回溯过程。

#include<iostream>
#include<string>
#include<vector>
#include<stack>

using namespace std;

class Solution {
private:
    const string letterMap[8] ={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> ret;
public:
    //此时s中保存了digits[0,1,...,index-1]翻译到的字符串
    //寻找digits[index]匹配的字母,获得digits[0,1,...,index]翻译到的字符串
    void combination(const string &digits, int index, string s)
    {
        cout<<index<<" : "<<s<<endl;
        if(index == digits.size())
        {
            cout<<"get : "<<s<<",return"<<endl;
            ret.push_back(s);
            return;
        }

        string letter = letterMap[digits[index] - '2'];
        for(int i = 0; i < letter.size(); i++)
        {
            cout<<"digits["<<index<<"]:"<<digits[index]<<", use "<<letter[i]<<endl;
            combination(digits, index+1, s+letter[i]);
        }
        cout<<"digits["<<index<<"]:"<<digits[index]<<", complete return"<<endl;
        return;
    }
    vector<string> letterCombinations(string digits) {
        if(digits.size() == 0)
            return ret;
        combination(digits, 0, "");
        return ret;
    }
};

int main()
{
    Solution solve;
    string digits;
    cin>>digits;
    vector<string> ret = solve.letterCombinations(digits);
    for(int i = 0; i < ret.size(); i++)
    {
        cout<<ret[i]<<endl;
    }
    return 0;
}

 

93. 复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]

class Solution {
private:
    vector<string> ret;
public:
    bool isValid(string s)
    {
        if(s.size() > 1 && s[0] == '0')
            return false;
        int ret = atoi(s.c_str());
        if(ret > 255)
            return false;
        return true;
    }
    void helper(const string &s, int index, int count, string temp)
    {
        if(count == 0)
        {
            if(index == s.length())
                ret.push_back(temp);
            return;
        }
        
        for(int i = 1; i <= 3; i++)
        {
            if(s.length() >= index+i)//不能超过字符串长度
            {
                string t = s.substr(index, i);
                if(!isValid(t))//判断取的数据是否合理,不能大于255,也不能是00,000
                    continue;
                if(count == 1)
                    helper(s, index+i, count-1, temp+t);
                else
                    helper(s, index+i, count-1, temp+t+".");
            } 
        }
        
        return;
    }
    vector<string> restoreIpAddresses(string s) {
        if(s.length() == 0)
            return ret;
        
        helper(s, 0, 4, "");
        return ret;
    }
};

131. 分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

输入: "aab"
输出:
[
  ["aa","b"],
  ["a","a","b"]
]

class Solution {
private:
    vector<vector<string>> ret;
public:
    vector<vector<string>> partition(string s) {
        vector<string> temp;
        DFS(s, temp, 0);
        return ret;
     }
    void DFS(string s, vector<string> &temp, int pos)
    {
        if(s.size() == pos)
        {
            ret.push_back(temp);
            return;
        }
        
        for(int i = pos; i <s.size();i++)
        {
            if(isPalindrome(s, pos, i))
            {
                temp.push_back(s.substr(pos, i-pos+1));
                DFS(s, temp, i+1);
                temp.pop_back();
            }
        }
    }
    bool isPalindrome(string s, int start, int end)
    {
        while(start < end)
        {
            if(s[start] != s[end])
                return false;
            start++;
            end--;
        }
        return true;
    }
};

一、回溯算法的应用,排列问题

46. 全排列

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

第一种方法回溯法

class Solution {
private:
    vector<vector<int> >ret;
    vector<bool> used;
public:
    //p中保存了index个元素的排列组合
    //向其中添加第index+1个元素的排列组合
    void helper(const vector<int> &num, int index, vector<int> p)
    {
        if(index == num.size())
        {
            ret.push_back(p);
            return;
        }
        
        for(int i = 0; i < num.size(); i++)
        {
            if(!used[i])
            {
                p.push_back(num[i]);
                used[i] = true;
                helper(num, index+1, p);
                p.pop_back();
                used[i] = false;
            }
        }
        
        return;
    }
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.size() == 0)
            return ret;
        
        used = vector<bool>(nums.size(), false);
        vector<int> p;
        helper(nums, 0,  p);
        
        return ret;
    }
};

第二种方法:

类似第31题,寻找下一个排列,将所有排列的情况保存起来。

下一个排列的方法:对当前排列从后向前扫描,找到一对为升序的相邻元素,记为i和j(i < j)。如果不存在这样一对为升序的相邻元素,则序列逆序排列,直接逆转序列,算法结束;否则,重新对当前排列从后向前扫描,找到第一个大于i的元素k,交换i和k,然后对从j开始到结束的子序列反转,则此时得到的新排列就为下一个字典序排列。

class Solution {
public:
    vector<vector<int> > permute(vector<int>& nums) 
    {
        sort(nums.begin(),nums.end());
		vector<vector<int> >result;
		result.push_back(nums);
		int i,j;
		while(1)
		{
			for(i=nums.size()-1;i>0;i--)
			{
				if(nums[i]>nums[i-1])
					break;
			}
			if(i==0)
				break;
			for(j=nums.size()-1;j>=i;j--)
			{
				if(nums[j]>nums[i-1])
				{
					swap(nums[j],nums[i-1]);
					break;
				}
			}
			reverse(nums.begin()+i,nums.end());
			result.push_back(nums);
		}
		return result;
    }
};

47. 全排列 II

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

class Solution {
private:
    vector<vector<int> >ret;
public:
    void helper(vector<int> num, int index, vector<int> p)
    {
        if(index == num.size())
        {
            ret.push_back(p);
            return;
        }
        
        for(int i = 0; i < num.size(); i++)
        {
            int c1 = 0, c2 = 0;
            if(!i || num[i] != num[i-1])//去除掉重复的情况
            {
                for(int j = 0; j < p.size(); j++)
                {
                    if(num[i] == p[j])
                        c1++;
                }
                for(int j = 0; j < num.size(); j++)
                {
                    if(num[i] == num[j])
                        c2++;
                }
                if(c1 < c2)//保证p中的num[i]的个数小于数组中num[i]的个数
                {
                    p.push_back(num[i]);
                    helper(num, index+1, p);
                    p.pop_back();
                }
            }
        }
        
        return;
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if(nums.size() == 0)
            return ret;
        
        vector<int> p;
        sort(nums.begin(), nums.end());
        helper(nums, 0, p);
        
        return ret;
    }
};

二、回溯算法应用,组合问题

77. 组合

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

class Solution {
private:
    vector<vector<int>> ret;
    //求解C(n, k), 当前已找到的组合存储在temp中,从start开始添加新的元素
    void helper(int n, int k, int start, vector<int> temp)
    {
        if(temp.size() == k)
        {
            ret.push_back(temp);
            return;
        
        }
        
        for(int i = start; i <= n ; i++)
        {
            temp.push_back(i);
            helper(n, k, i+1, temp);
            temp.pop_back();
        }
        
        return;
    }
public:
    vector<vector<int>> combine(int n, int k) {
        if(n == 0 || k == 0 || k > n)
            return ret;
        
        vector<int> temp;
        helper(n, k, 1, temp);
        
        return ret;
    }
};

对算法进行减枝

class Solution {
private:
    vector<vector<int>> ret;
    //求解C(n, k), 当前已找到的组合存储在temp中,从start开始添加新的元素
    void helper(int n, int k, int start, vector<int> temp)
    {
        if(temp.size() == k)
        {
            ret.push_back(temp);
            return;
        
        }
        //已添加元素的个数为temp.size(), 在[i,...,n]范围内至少还需要添加k - temp.size()个元素
        //i的最大值为n-(k-temp.size()) +1
        for(int i = start; i <= n-(k-temp.size()) +1 ; i++)
        {
            temp.push_back(i);
            helper(n, k, i+1, temp);
            temp.pop_back();
        }
        
        return;
    }
public:
    vector<vector<int>> combine(int n, int k) {
        if(n == 0 || k == 0 || k > n)
            return ret;
        
        vector<int> temp;
        helper(n, k, 1, temp);
        
        return ret;
    }
};

39. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

    所有数字(包括 target)都是正整数。
    解集不能包含重复的组合。

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

与上一题组合的不同之处在于,循环里面递归调用回溯函数中的start参数使用i而非i+1,因为题中允许存在重复元素

class Solution {
private:
    vector<vector<int>> ret;
    void helper(vector<int>& candidates, vector<int> temp, int target, int start)
    {
        if(target <= 0)
        {
            if(target == 0)
                ret.push_back(temp);
            return;
        }
        
        for(int i = level; i < candidates.size(); i++)
        {
            temp.push_back(candidates[i]);
            helper(candidates, temp, target - candidates[i], i);
            temp.pop_back();
        }
        
        return;
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> temp;
        helper(candidates, temp, target, 0);
        return ret;
    }
};

40. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

    所有数字(包括目标数)都是正整数。
    解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

这里每个数字只能出现一次,因此start的值是i+1不是i

class Solution {
private:
    vector<vector<int>> ret;
    void helper(vector<int>& candidates, int target, vector<int> temp, int start)
    {
        if(target <= 0)
        {
            if(target == 0)
                ret.push_back(temp);
            return;
        }
        
        for(int i = start; i < candidates.size(); i++)
        {
            if(i != start && candidates[i] == candidates[i-1])//1,1开头,排除第二个1,跟前面的结果重复了
                continue;
            target = target - candidates[i];
            temp.push_back(candidates[i]);
            helper(candidates, target, temp, i+1);
            temp.pop_back();
            target = target + candidates[i];
        }
        
        return;
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector<int> temp;
        
        helper(candidates, target, temp, 0);
        return ret;
    }
};

216. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

    所有数字都是正整数。
    解集不能包含重复的组合。

示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]

示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

这道题控制的变量变成了两个,同时不能有重复的数字。

class Solution {
private:
    vector<vector<int>> ret;
    void helper(int k, int n, vector<int> temp, int start)
    {
        if(n <= 0)
        {
            if(n == 0 && k == 0)
                ret.push_back(temp);
            return;
        }
        
        for(int i = start; i <= 9; i++)
        {
            temp.push_back(i);
            helper(k - 1, n - i, temp, i+1);
            temp.pop_back();
        }
        
        return;
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        if(k > n)
            return ret;
        
        vector<int> temp;
        helper(k, n, temp, 1);
        
        return ret;
    }
};

78. 子集

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

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

90. 子集 II

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2]
输出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

class Solution {
private:
    vector<vector<int>> ret;
    void helper(vector<int> nums, int count, int start, vector<int> temp)
    {
        if(temp.size() == count)
        {
            ret.push_back(temp);
            return;
        }
        
        for(int i = start; i < nums.size(); i++)
        {
            if(i!=start && nums[i] == nums[i-1])
                continue;
            temp.push_back(nums[i]);
            helper(nums, count, i+1, temp);
            temp.pop_back();
        }
        
        return;
    }
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        vector<int> temp;
        ret.push_back(temp);
        sort(nums.begin(), nums.end());
        
        for(int i = 1; i <= nums.size(); i++)
            helper(nums, i, 0, temp);
        
        return ret;
    }
};

三、二维平面上使用回溯法

79. 单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.

class Solution {
private:
    int dir[4][2] = {{-1,0}, {1, 0}, {0, -1}, {0, 1}};
    vector<vector<bool> >visit;
    bool search(vector<vector<char>>& board, string word, int index, int x, int y)
    {
        if(index == word.size() - 1)
            return word[index] == board[x][y];
        
        if(board[x][y] == word[index])
        {
            visit[x][y] = true;
            for(int i = 0; i < 4; i++)
            {
                int newx = x + dir[i][0];
                int newy = y + dir[i][1];
            
                if(newx < 0 || newx >= board.size() || newy < 0 || newy >= board[0].size() ||  visit[newx][newy])
                    continue;
                if(search(board, word, index+1, newx, newy))
                    return true;
            }
            visit[x][y] = false;
        }
        
        return false;
        
    }
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();
        
        if(m == 0 || word.length() == 0)
            return false;
        
        visit = vector<vector<bool>>(m, vector<bool>(n, false));
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(search(board, word, 0, i, j))
                    return true;
        
        return false;
    }
};

floodfill算法,也可以叫做DFS算法

200. 岛屿数量

给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3

class Solution {
private:
    int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
public:
    int numIslands(vector<vector<char>>& grid) {
        if(grid.empty() || grid[0].empty())
            return 0;
        int m = grid.size(), n = grid[0].size();
        int res = 0;
        vector<vector<bool> >visit(m, vector<bool>(n, false));
        for(int i = 0;i < m;i++)
            for(int j = 0; j < n;j++)
            {
                if(grid[i][j] == '1' && !visit[i][j])
                {
                    numIslandsDFS(grid, visit, i, j);
                    res++;
                }
            }
        return res;
    }
    
    void numIslandsDFS(vector<vector<char>>& grid, vector<vector<bool> >&visit, int x, int y)
    {
        visit[x][y] = true;
        for(int i = 0; i < 4; i++)
        {
            int newx = x + dir[i][0];
            int newy = y + dir[i][1];
            if(newx < 0 || newx >= grid.size() || newy < 0 || newy >= grid[0].size() || visit[newx][newy])
                continue;
            if(grid[newx][newy] == '1')
                numIslandsDFS(grid, visit, newx, newy);
        }
        
        return ;
    }
};

51. N皇后

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

示例:

输入: 4
输出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

class Solution {
private:
    vector<vector<string>> ret;
    vector<bool>col;
    vector<bool>diag1;
    vector<bool>diag2;
    vector<string> generate(int n, vector<int> pos)
    {
        vector<string> res;
        for(int i = 0; i < n; i++)
        {
            string temp = "";
            for(int j = 0; j < n; j++)
            {
                if(j != pos[i])
                    temp = temp + ".";
                else
                    temp = temp + "Q";
            }
            res.push_back(temp);
        }
        return res;
    }
    
    void search(int n, int row, vector<int> pos)
    {
        if(row == n)
        {
            vector<string> temp = generate(n, pos);
            ret.push_back(temp);
            return;
        }
        
        for(int i = 0; i < n; i++)
        {
            if(!col[i] && !diag1[row+i] && !diag2[row-i+n-1])
            {
                col[i] = true;
                diag1[row+i] = true;
                diag2[row-i+n-1] = true;
                pos.push_back(i);
                search(n, row+1, pos);
                col[i] = false;
                diag1[row+i] = false;
                diag2[row-i+n-1] = false;
                pos.pop_back();
            }
        }
        
        return;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
        if(n < 1)
            return ret;
        vector<int> pos;
        col = vector<bool>(n, false);
        diag1 = vector<bool>(2*n-1, false);
        diag2 = vector<bool>(2*n-1, false);
        search(n, 0, pos);
        
        return ret;
    }
};

52. N皇后 II

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

示例:

输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]

class Solution {
private:
    int count;
    vector<bool>col;
    vector<bool>diag1;
    vector<bool>diag2;
    void search(int n, int row)
    {
        if(row == n)
        {
            count++;
            return;
        }
        
        for(int i = 0; i < n; i++)
        {
            if(!col[i] && !diag1[row+i] && !diag2[row-i+n-1])
            {
                col[i] = true;
                diag1[row+i] = true;
                diag2[row-i+n-1] = true;
                search(n, row+1);
                col[i] = false;
                diag1[row+i] = false;
                diag2[row-i+n-1] = false;
            }
        }
        
        return;
    }
public:
    int totalNQueens(int n) {
        if(n < 1)
            return 0;
        count = 0;
        
        col = vector<bool>(n, false);
        diag1 = vector<bool>(2*n-1, false);
        diag2 = vector<bool>(2*n-1, false);
        search(n, 0);
        
        return count;
    }
};

37. 解数独

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

    数字 1-9 在每一行只能出现一次。
    数字 1-9 在每一列只能出现一次。
    数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

一个数独。

答案被标成红色。

Note:

    给定的数独序列只包含数字 1-9 和字符 '.' 。
    你可以假设给定的数独只有唯一解。
    给定数独永远是 9x9 形式的。

class Solution {
private:
    bool check(vector<vector<char>>& board, int i, int j, char c)
    {
        //行没有重复元素
        for(int x = 0; x < 9; x++)
            if(board[x][j] == c)
                return false;
        //列没有重复元素
        for(int y = 0; y < 9; y++)
            if(board[i][y] == c)
                return false;
        //九宫格没有重复元素
        int row = i - i%3;
        int col = j - j%3;
        for(int x = 0; x < 3; x++)
            for(int y = 0; y < 3; y++)
            {
                if(board[row+x][col+y] == c)
                    return false;
            }
        return true;
    }
    bool solve(vector<vector<char>>& board, int i, int j)
    {
        if(i == 9)
            return true;
        if(j == 9)
            return solve(board, i+1, 0);
        if(board[i][j] != '.')
            return solve(board, i, j+1);
        
        for(char c = '1'; c <= '9'; c++)
        {
            if(check(board, i, j, c))
            {
                board[i][j] = c;
                if(solve(board, i, j+1))
                   return true;
                board[i][j] = '.';
            }
        }
        
        return false;
    }
public:
    void solveSudoku(vector<vector<char>>& board) {
        solve(board, 0, 0);
    }
};

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值