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.
A sudoku puzzle...
...and its solution numbers marked in red.
完成数独游戏,目前空的小方格被标记为'.'。
数独游戏规则:规则以及区块的定义在上一个题目Valid Sudoku中介绍过(行、列、区块中每个数字只用一次,均不能重复)。
在LeetCode官网本道题的Dission区有很多好的巧妙的解决方达。我看了一下,懒一点就选了一个最好理解的.....
JAVA解决方法:对每个要填的空从‘1’试到‘9’,时间复杂度是 9 ^ n(n是要填的空有几个)。
public class Solution { public void solveSudoku(char[][] board) { if(board == null || board.length == 0) return; solve(board); } public boolean solve(char[][] board){ for(int i = 0; i < board.length; i++){ for(int j = 0; j < board[0].length; j++){ if(board[i][j] == '.'){ for(char c = '1'; c <= '9'; c++){ //一个个尝试,从‘1’试到‘9’ if(isValid(board, i, j, c)){ //isValid函数先判断这个数字是否重复 board[i][j] = c; //把数字填入 if(solve(board)) //如果填的这个数以至于之后可以完成数独,等继续完成之后,就返回true return true; else //如果填的这个数字,导致之后无法完成整个数独,就把这个空重新置为空(说明填上c这个数字不合适),之后尝试其他数字 board[i][j] = '.'; } } return false; } } } return true; } private boolean isValid(char[][] board, int row, int col, char c){ //判断c是否在当前行、列、区块已经存在 for(int i = 0; i < 9; i++) { if(board[i][col] != '.' && board[i][col] == c) return false; //判断列 if(board[row][i] != '.' && board[row][i] == c) return false; //判断行 if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' && board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //判断当前区块3*3的九个位置 } return true; } }
至于区块为什么这么来算?
board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.'
之后再更新。。。