解数独 |刷题打卡

293 阅读2分钟

掘金团队号上线,助你 Offer 临门! 点击 查看大厂春招职位

一、题目描述:

编写一个程序,通过填充空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 '.' 表示。

提示:

  • 给定的数独序列只包含数字 1-9 和字符 '.' 。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

题目地址:leetcode-cn.com/problems/su…

二、思路分析:

由于提示数独只有一个唯一解,所以不用考虑无解和多解的情况,所以解法就与排列数类似了。记录每一行,每一列,每一个小九宫格中出现的数字情况,然后进行深度优先搜索。

使用3个二维数组,分别记录 每一行、每一列、每个小九宫格里已经出现的数字。下标代表数字,值代表是否出现过然后使用 DSF。对每个需要填充的单元格进行递归。递归时根据之前统计的3个二维数组来判断应该填哪个数字

三、AC 代码:


    public static boolean filling(char[][] board, int[][] row, int[][] col, int[][] square) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') {
                    for (int k = 0; k < 9; k++) {
                        int sIndex = i / 3 * 3 + j / 3;
                        if (row[i][k] == 0 && col[j][k] == 0 && square[sIndex][k] == 0) {
                            board[i][j] = ((k + 1) + "").charAt(0);
                            row[i][k] = col[j][k] = square[sIndex][k] = 1;
                            if (filling(board, row, col, square)) {
                                return true;
                            } else {
                                board[i][j] = '.';
                                row[i][k] = col[j][k] = square[sIndex][k] = 0;
                            }
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    public static void solveSudoku(char[][] board) {
        int[][] row = new int[9][9];
        int[][] col = new int[9][9];
        int[][] square = new int[9][9];
        //init array
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int num = board[i][j] - '0' - 1;
                    //根据 i、j 计算属于第几个九宫格
                    int sIndex = i / 3 * 3 + j / 3;
                    row[i][num] = col[j][num] = square[sIndex][num] = 1;
                }
            }
        }
        filling(board, row, col, square);
    }

四、总结:

很笨的一种方法,但是比较容易理解,LeetCode 上有一种利用位运算解法。但是不太容易想明白。