Leetcode (37) Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character ‘.’.

You may assume that there will be only one unique solution.

  • 题意:求解数独游戏,给定的board里面空缺的位置用’.’来表示,即board中的数字也是char类型

  • 思路:不知道数独是不是像魔方那样有一定的求解公式,而回忆自己做数独题的过程中,往往都会找到一些必然确定的位置,先填上,再逐步完成游戏。而存在必然确定的位置,一般都是一些比较低级的数独,而高级一点的常常要尝试,若是找到矛盾就回到原来位置,逐步排除,最后完成。

  • 实际上这就是一种深搜,失败则回溯修改再次尝试的策略,利用计算机的高速计算能力则可以不停地进行尝试,最终完成游戏。
  • 而实际上,可以往里面添加一点策略,进而达到剪枝的效果。比如说,数独游戏的规则要保证每一行、每一列、每个九宫格内的数字都要不同,那么如果尝试的数字违反了这一规则,那么必然可以直接排除,就跟我们平时玩的时候一样,达到剪枝的效果。

  • PS: 实际上搜索顺序还会影响到求解速度,比如说,先填写数字比较多的行或者列,能够尽快排除掉错误答案,找到正解,还能进一步优化!

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        memset(nums,0,sizeof(nums));
        memset(nn,0,sizeof(nn));
        for (int i=0;i<9;i++)
        {
            for (int j=0;j<9;j++)
            {
                int n;
                if (board[i][j]=='.') n=0;
                else n = board[i][j] - '0';
                chart[i][j] = n; 
                nums[0][i][n] = nums[1][j][n] = nn[i / 3][j / 3][n] = 1;
            }
        }
        dfs(8,8);
        for (int i=0;i<9;i++)
        {
            for (int j=0;j<9;j++)
            {
                board[i][j] = chart[i][j] + '0'; 
            }
        }
    }
private:
    int chart[10][10]; 
    bool ok, nums[2][10][10], nn[3][3][10];
    void dfs(int x, int y) {
        if (chart[x][y] != 0) {
            if (x == 0 && y == 0)ok = true;
            else if (y == 0)dfs(x - 1, 8);
            else dfs(x, y - 1);
        }
        else {
            for (int i = 1; i <= 9; i++)
                if (nums[0][x][i] == 0 && nums[1][y][i] == 0 && nn[x / 3][y / 3][i] == 0) {
                    nums[0][x][i] = nums[1][y][i] = nn[x / 3][y / 3][i] = 1;
                    chart[x][y] = i;
                    if (x == 0 && y == 0)ok = true;
                    else if (y == 0)dfs(x - 1, 8);
                    else dfs(x, y - 1);
                    if (ok) return;
                    nums[0][x][i] = nums[1][y][i] = nn[x / 3][y / 3][i] = 0;
                    chart[x][y] = 0;
                }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值