Leetcode37 Sudoku Solver

Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character ‘.’.

You may assume that there will be only one unique solution.

Solution

  • 典型的利用回溯方法求解的题。因为没有什么准确的算法直接求解,只能一个一个去尝试。基本思路是:针对数独的每一行去遍历,找到一个不与当前状态冲突的数尝试填在这个位置上,然后往后继续尝试,如果尝试到某一位置时,已经无法填上任何一个数了则开始回溯。代码如下:
public class Solution {
    boolean[][] rows = new boolean[9][9];
    boolean[][] cols = new boolean[9][9];
    boolean[][] grids = new boolean[9][9];
    boolean flag = false;
    public void solveSudoku(char[][] board) {
        if(board.length!=9) return;
        if(board[0].length!=9) return;

        for(int i=0;i<9;i++){//先记录一遍目前数独中的初始状态
            for(int j=0;j<9;j++){
                char c = board[i][j];
                if(c=='.') continue;
                rows[i][c-'1'] = true;
                cols[j][c-'1'] = true;
                grids[i/3*3+j/3][c-'1'] = true;
            }
        }
        help(board,0,0);
    }
    public void help(char[][] board,int row,int col){
        if(row>=9){//已经找到了数独的解
            flag = true;
            return;
        }
        char c = board[row][col];
        if(c=='.'){//当前是一个空格
            for(int i=0;i<=8;i++){//从1到9遍历的去尝试
                if(rows[row][i]||cols[col][i]||grids[row/3*3+col/3][i]) continue;//新填入的数不能和数独中已有的状态产生冲突
                rows[row][i] = true;
                cols[col][i] = true;
                grids[row/3*3+col/3][i] = true;
                board[row][col] = (char)(i + '1');//暂时先填上这个数

                if(col>=8) help(board,row+1,0);//到了该行的末尾,从下一行的头部开始
                else help(board,row,col+1);//继续去考察下一格

                if(flag) return;//如果已经找到答案了则直接返回
                rows[row][i] = false;//尝试的当前数不合适,继续尝试下一个数
                cols[col][i] = false;
                grids[row/3*3+col/3][i] = false;
                board[row][col] = '.';
            }
        }else if(col>=8) help(board,row+1,0);
        else help(board,row,col+1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值