LeetCode T37 Sudoku Solver

题目地址

中文:https://leetcode-cn.com/problems/sudoku-solver/
英文:https://leetcode.com/problems/sudoku-solver/

题目描述

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

A sudoku solution must satisfy all of the following rules:

  • Each of the digits 1-9 must occur exactly once in each row.
  • Each of the digits 1-9 must occur exactly once in each column.
  • Each of the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
    The ‘.’ character indicates empty cells.

Example 1:

在这里插入图片描述

Input: board = 
[["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]]
Output: 
[["5","3","4","6","7","8","9","1","2"],
["6","7","2","1","9","5","3","4","8"],
["1","9","8","3","4","2","5","6","7"],
["8","5","9","7","6","1","4","2","3"],
["4","2","6","8","5","3","7","9","1"],
["7","1","3","9","2","4","8","5","6"],
["9","6","1","5","3","7","2","8","4"],
["2","8","7","4","1","9","6","3","5"],
["3","4","5","2","8","6","1","7","9"]]
Explanation: The input board is shown above and the only valid solution is shown below:

在这里插入图片描述

Constraints:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] is a digit or ‘.’.
  • It is guaranteed that the input board has only one solution.

思路

扑面而来的N皇后的感觉,用递归解。
注意回溯的时候修改对应的变量。
参考https://blog.csdn.net/qq_31650113/article/details/112287027

题解

class Solution {
    int pos = 0;//遍历每个位置
    boolean isPreSolve = false;
    char[][] infill = new char[9][9];
    Map<Character,Integer>[] row = new HashMap[9];//row[i]表示第i行
    Map<Character,Integer>[] column = new HashMap[9];
    Map<Character,Integer>[] box = new HashMap[9];//box[i]表示第i个3*3格子

    public void preSolve(char[][] board){
        isPreSolve = true;
        for (int i = 0; i < 9; i++) {
            row[i] = new HashMap<Character, Integer>();
            column[i] = new HashMap<Character, Integer>();
            box[i] = new HashMap<Character, Integer>();
        }
        for(int i=0;i<9;++i)
            for(int j=0;j<9;++j)
                if(board[i][j]!='.'){
                    int k = i/3 + (j/3)*3;
                    row[i].put(board[i][j], row[i].getOrDefault(board[i][j],0)+1);
                    column[j].put(board[i][j],column[j].getOrDefault(board[i][j],0)+1);
                    box[k].put(board[i][j],box[k].getOrDefault(board[i][j],0)+1);
                }
    }

    public void solveSudoku(char[][] board) {
        if(pos==81) {
            for(int i=0;i<9;++i)
                for(int j=0;j<9;++j)
                    if(board[i][j]=='.')
                        board[i][j] = infill[i][j];
            return;
        }

        if(!isPreSolve) preSolve(board);

        int i = pos/9;
        int j = pos%9;
        if(board[i][j]=='.'){
            int k = i/3 + (j/3)*3;
            for(int t=1;t<=9;++t){
                char temp = (char)('0'+t);
                if(row[i].getOrDefault(temp,0)!=0) continue;
                else if(column[j].getOrDefault(temp,0)!=0) continue;
                else if(box[k].getOrDefault(temp,0)!=0) continue;
                //满足条件就填上
                infill[i][j] = temp;
                row[i].put(temp, row[i].getOrDefault(temp,0)+1);
                column[j].put(temp,column[j].getOrDefault(temp,0)+1);
                box[k].put(temp,box[k].getOrDefault(temp,0)+1);
                pos++;
                solveSudoku(board);
                pos--;
                row[i].put(temp, row[i].getOrDefault(temp,0)-1);
                column[j].put(temp,column[j].getOrDefault(temp,0)-1);
                box[k].put(temp,box[k].getOrDefault(temp,0)-1);
            }
        }else{
            pos++;
            solveSudoku(board);
            pos--;
        }


    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值