qingcheng奕  

https://oj.leetcode.com/problems/sudoku-solver/

九宫格数独问题。

一行上为1 2 3 到9

一列上为1 2 3 到9

每个小的3*3格子为 1 2 3 到9

使用深搜递归实现:

在技巧上,使用类的成员变量 vector<vector<char> > board; 这样不用每层递归都传递这个棋盘了

              使用类的成员变量 bool flagOK; 标志是否已找到 solution.

从(0,0)位置开始递归,一个个位置加,直到位置到了最后一个。

在每一层上,遍历1 2 3 到 9 ,看看哪个数可以往这里放,然后递归下一层,即下一个位置。

当从下一个位置返回的时候,要把之前设置的值再 恢复 回来

还有个情况会导致返回到上一次,那就是从1 到 9 都遍历完了,仍然都不可以,也要记得恢复回来

class Solution {
public:
    vector<vector<char> > board;
    bool flagOK;
    void solveSudoku(vector<vector<char> > &board) {
        if(board.empty())
            return;
        flagOK = false;
        this->board = board;
        subSudoku(0,0);
        board = this->board;
    }
    
    // in rows and cols don't have the same one 
    bool valide(char num, int p, int q)
    {
        bool flag = true;
        for(int i = 0; i < board.size(); i++)
        {
            if(num == board[i][q])
            {
                flag = false;
                break;
            }
        }
        if(flag)
        {
            for(int j = 0; j < board.size(); j++)
            {
                if(num == board[p][j])
                {
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }
    
    void subSudoku(int i, int j)
    {
        // till end find solution
        if(i == board.size())
        {
            flagOK = true;
            return;
        }
           
            
        // num placed
        if(board[i][j] != '.')
        {
            if(j < board.size() - 1)
            {
                subSudoku(i,j + 1);
                if(flagOK == true)
                    return; //不再递归了,已经找到答案了
            }
            else
            {
                subSudoku(i+1,0);
                if(flagOK == true)
                    return;
            }
        }
        else
        {
            char num;
            for(num = '1'; num <= '9'; num++)
            {
                // in its small cube
                bool OKSmallCube = true;
                int smallCubeI = i/3;
                int smallCubeJ = j/3;
                // check small cube
                for(int s = 0; s < 3; s++)
                {
                    for(int m = 0; m < 3; m++)
                    {
                        if(board[smallCubeI*3 + s][smallCubeJ*3 + m] == num)
                        {
                            OKSmallCube = false;
                            break;
                        }
                    }
                    if(OKSmallCube == false)
                        break;
                }
                
                if(OKSmallCube && valide(num,i,j))
                {
                    board[i][j] = num;
                    if(j < board.size() - 1)
                    {
                        subSudoku(i,j + 1);
                        if(flagOK == true)
                            return;
                    }
                    else
                    {
                        subSudoku(i+1,0);
                        if(flagOK == true)
                            return;
                    }
                }
                board[i][j] = '.';  //注意恢复原样
            }
            board[i][j] = '.';//注意恢复原样
        }
    }
};
 

 

posted on 2014-07-31 20:59  qingcheng奕  阅读(153)  评论(0编辑  收藏  举报