Leetcode:37. 解数独

Leetcode: 37.解数独

题目描述

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。



一个数独。



答案被标成红色。

Note:

给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

思路

思路1

使用回溯法,利用受行、列、3*3矩阵约束,进行回溯

代码

代码1

class Solution {
    char[][] board;
    int[][] rowCount = new int[9][9];
    int[][] columnCount = new int[9][9];
    int[][] matrixCount = new int[9][9];
    boolean canSolve = false;

    private boolean canSet(int row, int column, int num){
        int matrixIndex = (row / 3) * 3 + column / 3;
        return rowCount[row][num - 1] == 0 && columnCount[column][num - 1] == 0 && matrixCount[matrixIndex][num - 1] == 0;
    }

    private void setNum(int row, int column, int num){
        int matrixIndex = (row / 3) * 3 + column / 3;
        rowCount[row][num - 1] += 1;
        columnCount[column][num - 1] += 1;
        matrixCount[matrixIndex][num - 1] += 1;
        board[row][column] = (char)('0' + num);
    }

    private void removeNum(int row, int column, int num){
        int matrixIndex = (row / 3) * 3 + column / 3;
        rowCount[row][num - 1] -= 1;
        columnCount[column][num - 1] -= 1;
        matrixCount[matrixIndex][num - 1] -= 1;
        board[row][column] = '.';
    }

    private void setNext(int row, int column){
        if (row == 8 && column == 8){
            this.canSolve = true;
        }
        if (column != 8){
            backTrack(row, column + 1);
        }else{
            backTrack(row + 1, 0);
        }
    }

    private void backTrack(int row, int column){
        if (row > 8 || column > 8){
            return;
        }
        if (this.board[row][column] == '.'){
            for(int i = 1; i < 10; i++){
                if (canSet(row, column, i)){
                    setNum(row, column, i);
                    setNext(row, column);
                    if (!this.canSolve){
                        removeNum(row, column, i);
                    }
                }
            }
        }else{
            setNext(row, column);
        }
    }

    public void solveSudoku(char[][] board) {
        this.board = board;
        for(int i = 0; i < 9; i++){
            for(int j=0; j < 9; j++){
                if (this.board[i][j] != '.'){
                    int num = (int)(this.board[i][j] - '0');
                    setNum(i, j, num);
                }
            }
        }
        backTrack(0, 0);
    }
}

复杂度分析

思路1时间复杂度

$(n!)^9$

思路1空间复杂度

$n^2$


文章作者: 小风雷
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小风雷 !
评论
 上一篇
Leetcode:39. 组合总和 Leetcode:39. 组合总和
[Leetcode](Leetcode: 39. 组合总和)题目描述给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidate
2020-06-07
下一篇 
Leetcode:146. LRU缓存机制 Leetcode:146. LRU缓存机制
Leetcode:146. LRU缓存机制题目描述运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。 获取数据 get(key) - 如果密钥 (k
2020-05-14
  目录