LeetCode 37. Sudoku Solver

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.

pic_1

A sudoku puzzle…

pic_2

..and its solution numbers marked in red.

分析

根据题目,我们可以获得以下信息:

  • 这是个数独问题。即同一行同一列和同一个三阶方阵内的数字不能重复。

  • 假设答案只有一个。即我们要用到深度优先搜索,找到答案后及时回溯。

根据这两个特点我采用了以下策略:

  • 用递归的方法从左到右从上到下,逐渐完善这张图

  • 如果得到最终答案,则停止递归。

  • 如果这张图的下一个空位得不到任何一个符合要求的数字,则停止这次递归。

  • 用一个函数实现递归。

  • 用一个函数实现得到符合要求的数字列表。

实现代码

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        vector<vector<char>> result;
        solveSudoku_iterator(0,0,board, result);
        board = result;
    }
private:
    void solveSudoku_iterator(int start_i,int start_j,vector<vector<char>> board, vector<vector<char>>& result) {
        if (!result.empty())return;
        int j = start_j;
        for (int i = start_i; i < 9; i++)
        {
            for (; j < 9; j++)
            {
                if (board[i][j] == '.')
                {
                    vector<int> num;
                    get_num(board, i, j,num);
                    if (num.empty())return;
                    while (!num.empty())
                    {
                        board[i][j] = 48 + num.back();
                        solveSudoku_iterator(i,j, board, result);
                        num.pop_back();
                    }
                    return;
                }
            }
            j = 0;
        }
        result = board;
    }
    void get_num(vector<vector<char>>& board,int& x,int& y, vector<int>& num)
    {
        for (int n = 1 ; n < 10; n++)
        {
            bool pass = true;
            for (int r_index = 0; r_index < 9 && pass; r_index++)
            {
                if (board[r_index][y] == n + 48 && r_index != x)pass = false;
            }
            for (int c_index = 0; c_index < 9 && pass; c_index++)
            {
                if (board[x][c_index] == n + 48 && c_index != y)pass = false;
            }
            for (int x_mod = (x / 3) * 3; x_mod < (x / 3 + 1)* 3 && pass; x_mod++)
                for (int y_mod = (y / 3) * 3; y_mod < (y / 3 + 1) * 3 && pass; y_mod++)
                    if (board[x_mod][y_mod] == n + 48 && (x_mod != x || y_mod != y))pass = false;
            if (pass)num.push_back(n);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值