LeetCode 37 解数独

题目

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

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

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

注意:

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

解法

本道题类似于八皇后问题,在填充的位置放入1~9 数字,能放入的就继续往下走继续放,如果放的数字导致后面的不能放入就进行回溯。

首先,建立三个 二维数组 用来标记每行每列和每个格子能放入数字的条件,用来判断当前位置能不能放入这个数字
然后进行循环递归

class Solution {
    public void solveSudoku(char[][] board) {
      //用来判断放入的数字是否符合数独
        boolean[][] row = new boolean[9][9];
        boolean[][] col = new boolean[9][9];
        boolean[][] box = new boolean[9][9];
        //填充表格中已经存在的数字
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int n = board[i][j] - '1';
                    row[i][n] = true;
                    col[j][n] = true;
                    box[i / 3 * 3 + j / 3][n] = true;
                }
            }
        }
        dfs(board, row, col, box, 0, 0);
    }

    private boolean dfs (char[][] board, boolean[][] row, boolean[][] col, boolean[][] box, int i, int j) {
        //判断边界条件,达到数独最后位置后返回true
        if(j == board[0].length){
            j = 0;
            i++;
            if(i == board.length){
                return true;
            }
        }
        //如果当前位置能填充
        if (board[i][j] == '.'){
        //遍历1-9数字填充
         for (int n = 1; n <= 9; n++) {
            int boxIndex = i / 3 * 3 + j / 3;
            //判断填充的数字是否符合数独条件
            if (!row[i][n-1] && !col[j][n-1] && !box[boxIndex][n-1]) {
                board[i][j] = (char) ('0' + n);
                row[i][n-1] = true;
                col[j][n-1] = true;
                box[boxIndex][n-1] = true;
                //符合条件,则继续往下一个位置填充
                if (dfs(board,row,col,box,i,j + 1)) {
                    return true;
                }
                //不然的话,就回溯
                row[i][n-1] = false;
                col[j][n-1] = false;
                box[boxIndex][n-1] = false;
                board[i][j] = '.';
            }
         }
        } else {//当前位置不是空格,就往下一个位置填充
            return dfs(board, row, col, box, i, j + 1);
        }
        //如果没有达到边界条件,但是已经1-9数字都不能填充进去,就返回false,数独不能填充完成
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值