Leetcode : Sudoku Solver

连接:

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值