Leetcode : Sudoku Solver

来源:互联网 发布:淘宝劲霸男装春秋夹克 编辑:程序博客网 时间:2024/06/07 20:06

连接:

https://leetcode.com/problems/sudoku-solver/#/description

大概题意:

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.

解题思路:

此题第一感觉就是使用递归+回溯基本就可以了,开始还以为会超时什么的,大概估算一下每一个格子最多就是9!种情况,应该时间复杂度还好。下面给出代码。
public class Solution {    private static final char[] elems = new char[]{'1','2','3','4','5','6','7','8','9'};//后面方便使用    private char[][]board;//用一个私有变量吧,省得后面传来传去的    public void solveSudoku(char[][] board) {        this.board = board;        solveSudokuHelper(0);//开始从0位置开始就行了,具体看下面代码    }//下面递归函数,这里把9宫格变成序号的形式,第一行:0~8;第二行9~17;后面依次类推    public boolean solveSudokuHelper(int seqNo){        //格子编号从0~80,如果是81则表示遍历完成,可以返回了,一定是返回true(开始的时候我搞成了void返回类型,导致回溯的时候无法判断是否成功,进而无法判断board中的格子值是要保留还是赋回原值)        if(seqNo==81) return true;        int x = seqNo/9;//将序号转为行号        int y = seqNo%9;//将序号转为列号        //非空直接进行下一个格子        if(this.board[x][y]!='.')            return solveSudokuHelper(seqNo+1);        else{        //如果是空格子,则开始一个个进行尝试            for(int k=0;k<9;k++){                if(check(x,y,elems[k])){                    //尝试成功,进行赋值和下一个格子                    this.board[x][y] = elems[k];                    if(solveSudokuHelper(seqNo+1)){                        return true;                    }                }            }            //程序能运行到此,表名前面的尝试并没有成功,所以需将x,y位置赋值为'.',并返回false            this.board[x][y]='.';            return false;        }    }//检查x,y位置是否可以放cur这个值    private boolean check(int x,int y,char cur){    //分别检查行、列、快是否满足        return checkBlockHelper(x,y,cur)&&checkColHelper(x,y,cur)&&checkRowHelper(x,y,cur);    }/***下面分别是对行、列、快的检查函数,很简单不再累赘*/    private boolean checkRowHelper(int x,int y,char cur){        for(int i=0;i<9;i++){            if((this.board[x][i]-'0')==(cur-'0'))                return false;        }        return true;    }    private boolean  checkColHelper(int x,int y,char cur){        for(int i=0;i<9;i++){            if((this.board[i][y]-'0')==(cur-'0'))                return false;        }        return true;    }    private boolean checkBlockHelper(int x,int y,char cur){        int xs = findStartIndex(x);        int ys = findStartIndex(y);        for(int i=xs;i<xs+3;i++){            for(int j=ys;j<ys+3;j++){                if((this.board[i][j]-'0')==(cur-'0'))                    return false;            }        }        return true;    }    //找到块的顶点    private int findStartIndex(int x){        return x/3*3;    }}

运行结果:
这里写图片描述

0 0