【题目】

每一行、每一列、每个3*3的格子里只能出现一次1~9。

【思路】

参考了思路,附加了解释。

dfs遍历所有非空格子,n是已经填好的个数。

初始化条件。n=81,都填了,返回结束。对于已经填好的b[x][y] != '.'跳过,到下一个。

xy的设计保证先行后列填写。

        if (n == 81) 
            return true;
        int x = n / 9;
        int y = n % 9;
        if (b[x][y] != '.') 
            return dfs(b, n + 1);

开始填数字,validate(b, x, y) && dfs(b, n + 1)共同确认是否填对。

        for (int i = 0; i < 9; i++) {
            b[x][y] = (char)('1' + i);//开始试数1~9
            if (validate(b, x, y) && dfs(b, n + 1)) 
                //试填后进行validate检验+填下一个n+1数,成功返true。
                return true;
            b[x][y] = '.';//否则擦除尝试,return false。
        }

 

validate函数,check每一行、每一列、每3*3的格子。
    public boolean validate(char[][] b, int x, int y) {
        for (int i = 0; i < 9; i++) {
            if (i != x && b[i][y] == b[x][y]) return false;
            if (i != y && b[x][i] == b[x][y]) return false;
        }
        int r = x / 3 * 3;//判断在哪个3*3的格子里
        int c = y / 3 * 3;
        for (int i = r; i < r + 3; i++) {
            for (int j = c; j < c + 3; j++) {
                if (i == x && j == y) continue;
                if (b[i][j] == b[x][y]) return false;
            }
        }
        return true;
    }

 

【代码】

class Solution {
    public void solveSudoku(char[][] board) {
        dfs(board, 0);
    }
    
    public boolean dfs(char[][] b, int n) {
        if (n == 81) 
            return true;
        int x = n / 9;
        int y = n % 9;
        if (b[x][y] != '.') 
            return dfs(b, n + 1);
        for (int i = 0; i < 9; i++) {
            b[x][y] = (char)('1' + i);
            if (validate(b, x, y) && dfs(b, n + 1)) return true;
            b[x][y] = '.';
        }
        return false;
    }
    
    public boolean validate(char[][] b, int x, int y) {
        for (int i = 0; i < 9; i++) {
            if (i != x && b[i][y] == b[x][y]) return false;
            if (i != y && b[x][i] == b[x][y]) return false;
        }
        int r = x / 3 * 3;//判断在哪个3*3的格子里
        int c = y / 3 * 3;
        for (int i = r; i < r + 3; i++) {
            for (int j = c; j < c + 3; j++) {
                if (i == x && j == y) continue;
                if (b[i][j] == b[x][y]) return false;
            }
        }
        return true;
    }
}

 

 posted on 2018-11-19 16:29  alau  阅读(169)  评论(0编辑  收藏  举报