• 问题介绍
    • 问题描述:Write a program to solve a Sudoku puzzle by filling the empty cells.A sudoku solution must satisfy all of the following rules:(Empty cells are indicated by the character ‘.’)
      • Each of the digits 1-9 must occur exactly once in each row.
      • Each of the digits 1-9 must occur exactly once in each column.
      • Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
    • 示例:
      • Sudoku Solver
    • 约束条件:NULL
  • 解决思路
    • 思路:
      • 分析题目后,解题思路类似于“八皇后”问题,可以采用回溯法解决该问题,使用递归编程;
      • 题目可以分为递归和check两部分;
      • 在回溯上,遍历所有为’.'节点,用1~9这九个值顺序去填充,填充后的矩阵再次执行相同的过程直到9X9的方阵中所有的点都有具体的赋值,此时返回;同时每次填充值后需要进行一个有效性检查,如果检查发现此时的矩阵无效,则需要返回到上一步骤,将当前填充的值返回为‘.’,换1~9中的下一个值进行赋值;
      • 在检查函数上check(),需要进行一个时间复杂度为O(n^2)的算法,建立三个vector,分别记录行、列、3X3小矩阵的合法性,每一个vector包含9个长度为9的int型数组,初始化时均为0,当矩阵board的第i行第j列为数字z的时候,对于行规则来说,对应于行vector的第i个数组的第z个元素,如果为0则将其值赋为1,表示第i行已经出现过数字z了,如果为1则返回false,因为z数字已经出现过了;对于列规则来说,对应于列vector的第j个数组;对于3X3小矩阵来说,对应于小矩阵vector的第(i/3)X3+j/3个数组;
  • 代码
class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        int pos=0;
        proc(board,pos);
    }
    bool proc(vector<vector<char>>& board,int pos)
    {
        if(pos==81)
            return true;
        else
        {
            int row=pos/9;
            int col=pos%9;
            if(board[row][col]=='.')
            {
                for(int i=1;i<10;i++)
                {
                    board[row][col]=48+i;
                    if(check(board))
                    {
                        if(proc(board,pos+1))
                            return true;
                    }
                    board[row][col]='.';
                }
            }
            else
            {
                if(proc(board,pos+1))
                    return true;
            }
        }
        return false;
    }
    
    bool check(vector<vector<char>>& board)
    {
        vector<vector<int>> visit_3(10,vector<int>(10,0));
        vector<vector<int>> visit_rows(10,vector<int>(10,0));
        vector<vector<int>> visit_cols(10,vector<int>(10,0));
        for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[i].size();j++)
            {

                if(board[i][j]>=48)
                {
                    //check rows
                    int n1=board[i][j]-48;
                    n1=board[i][j]-48;
                    if(visit_rows[i][n1]==0)
                    {
                        visit_rows[i][n1]=1;                        
                    }
                    else
                    {
                       return false;
                    }
                    //check cols
                    int n2=board[i][j]-48;
                    if(visit_cols[j][n2]==0)
                    {
                        visit_cols[j][n2]=1;
                    }
                    else
                    {
                        //cout<<"test2"<<endl;
                        return false;
                    }
                    //check 3x3
                    int row_num=i/3;
                    int col_num=j/3;
                    int n3=board[i][j]-48;
                    if(visit_3[row_num*3+col_num][n3]==0)
                    {
                        visit_3[row_num*3+col_num][n3]=1;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }
        return true;
    }
};

相关文章: