Leetcode #37. Sudoku Solver 数独求解 结题报告

1 解题报告

首先可以看下昨天的 Leetcode #36. Valid Sudoku 数独游戏验证 解题报告
数独的求解,这道题可以假设给定的这个是正确的

做法就只能是暴力的回溯了。。

  • 方法是回溯,用各个标志位来标志是否存在冲突
  • 如果数字原来就有了,那么就跳过处理
  • 因为答案只有一个,所以一旦找到,就要立马跳出递归(如果你用的是栈实现的回溯可能会好处理些)
  • 总之就是仔细些。。。我一次写过的,而且耗时貌似还很短。。。

    • 我没用题目提示的哈希,我用了数组去判断,因为这样快!!!,还有char数组还是先变成int数组吧,不然算起来很累。。

2 原题

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.

3 AC解

/** * 方法是回溯,用各个标志位来标志是否存在冲突 * 如果数字原来就有了,那么就跳过处理 * 因为答案只有一个,所以一旦找到,就要立马跳出递归(如果你用的是栈实现的回溯可能会好处理些) * 总之就是仔细些。。。我一次写过的,而且耗时貌似还很短。。。 * * 我没用题目提示的哈希,我用了数组去判断,因为这样快!!!,还有char数组还是先变成int数组吧,不然算起来很累。。 * * */
public class Solution {
    //各行各列的标志位
    boolean col[][]; //列
    boolean row[][]; //行
    boolean zone[][]; //九宫格内
    char result[][];
    //转换成正数
    int[][] tmp;
    boolean flag;
    public void find(int index){
        if(index==81){
             flag=true;
             for(int i=0;i<9;i++){
                 for(int j=0;j<9;j++){
                     result[i][j]=(char)('0'+tmp[i][j]);
                 }
             }
        }
        if(flag)
            return;   
        int i=index/9,j=index%9;
        if(tmp[i][j]==0){ // 此时等于0代表原来的是. 还没有数字进行填充,才进行运算,否则直接到下一个了
            for(int k=1;k<=9;k++){
                if(col[j][k]==false && row[i][k]==false && zone[(i/3)*3+j/3][k]==false){
                    /** * 递归的时候注意状态的改变,进入递归前先改变状态,跳出时要修正状态回来*/
                    col[j][k]=true;
                    row[i][k]=true;
                    zone[(i/3)*3+j/3][k]=true;
                    tmp[i][j]=k;
                    find(index+1);
                    tmp[i][j]=0;
                    col[j][k]=false;
                    row[i][k]=false;
                    zone[(i/3)*3+j/3][k]=false;
                }
            }
        }
        else{
            find(index+1);
        }

    }
    public void solveSudoku(char[][] board) {
        int i,j;
        result=board;
        flag=false;
        col=new boolean[9][10];
        row=new boolean[9][10];
        zone=new boolean[9][10];
        tmp=new int[9][9];
        //第一遍的扫描设置初始位置和标志位
        for(i=0;i<9;i++){
            for(j=0;j<9;j++){
                if(board[i][j]!='.'){
                    tmp[i][j]=board[i][j]-'0';
                    col[j][tmp[i][j]]=true;
                    row[i][tmp[i][j]]=true;
                    zone[(i/3)*3+j/3][tmp[i][j]]=true;
                }

            }
        }
        find(0);

    }
}

你可能感兴趣的:(LeetCode,递归,sudoku,栈,数独)