[深度优先搜索] leetcode 37 Sudoku Solver

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

        一道用dfs纯模拟的题目,每个空白先填一个可能的数字(行列方格都没出现的),先一直这么尝试把所有空白填满,到了没有数字可填的时候,就回退到上一步。通过不断地尝试,最终“试”出最终的答案。

class Solution {
public:
    int n;
    vector<vector<bool>> rows;
    vector<vector<bool>> cols;
    vector<vector<bool>> grid;
    bool bFind = false;

    void findNext(vector<vector<char>>& board, int x0, int y0, int& x, int& y)
    {
        for (int i = x0; i < n; i++)
        {
            int j = i == x0 ? y0 : 0;
            for ( ; j < n; j++)
            {
                if (i == x0 && j == y0) continue;
                if (board[i][j] == '.')
                {
                    x = i;
                    y = j;
                    return;
                }
            }
        }
        x = n;
        y = n;
    }
    void dfs(vector<vector<char>>& board, int i, int j, int count)
    {
        if (i == n && j == n)
        {
            if (count == 0)
            {
                bFind = true;
            }
            return;
        }
        
        int x, y;    
        findNext(board, i, j, x, y);
        int idx = (i / 3) * 3 + (j / 3);
        for (int k = 0; k < 9; k++)
        {
            if (!rows[i][k] && !cols[j][k] && !grid[idx][k])
            {
                board[i][j] = '1' + k;
                rows[i][k] = true;
                cols[j][k] = true;
                grid[idx][k] = true;

                dfs(board, x, y, count - 1);                
                if (bFind) return;

                rows[i][k] = false;
                cols[j][k] = false;
                grid[idx][k] = false;
            }
        }
        board[i][j] = '.';
    }
    void solveSudoku(vector<vector<char>>& board) {
        n = board.size();
        int target = 0;
        rows.resize(n, vector<bool>(9, false));
        cols.resize(n, vector<bool>(9, false));
        grid.resize(n, vector<bool>(9, false));
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (board[i][j] != '.')
                {
                    int idx = (i / 3) * 3 + (j / 3);
                    rows[i][board[i][j] - '1'] = true;
                    cols[j][board[i][j] - '1'] = true;
                    grid[idx][board[i][j] - '1'] = true;
                }
                else
                {
                    target++;
                }
            }
        }
        int x, y;
        findNext(board, 0, -1, x, y);
        if (x == n && y == n) return;
        dfs(board, x, y, target);
        
        //for (int i = 0; i < n; i++)
        //{
        //    for (int j = 0; j < n; j++)
        //    {
        //        cout << board[i][j] << " ";
        //    }
        //    cout << endl;
        //}

    }
};

 

posted @ 2019-08-01 14:40  fish1996  阅读(158)  评论(0)    收藏  举报