详细见:leetcode.com/problems/sudoku-solver
Java Solution: github
package leetcode;
/*
* 解数独
* 方法应该是试凑和回溯
*/
public class P037_SudokuSolver {
public static void main(String[] args) {
}
/*
* 还有很多bug
*/
static class Solution {
private boolean[][] isValidRow = new boolean[9][9];
private boolean[][] isValidColumn = new boolean[9][9];
private boolean[][] isValidNine = new boolean[9][9];
private boolean isSuccess = false;
public void solveSudoku(char[][] board) {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (board[i][j] != '.')
init(board, i, j);
solve(board, 0, 0);
}
private void solve(char[][] board, int i, int j) {
if (true == isSuccess)
return;
if (i > 8) {
isSuccess = true;
return;
}
if (board[i][j] != '.') {
if (j < 8)
solve(board, i, j + 1);
else
solve(board, i + 1, 0);
if (isSuccess)
return;
} else {
int temp = i / 3 * 3 + j / 3;
for (int n = 0; n < 9; n++) {
if (!isValidColumn[j][n] && !isValidRow[i][n] && !isValidNine[temp][n]) {
board[i][j] = (char) (n + '1');
isValidColumn[j][n] = isValidRow[i][n] = isValidNine[temp][n] = true;
if (j < 8)
solve(board, i, j + 1);
else
solve(board, i + 1, 0);
isValidColumn[j][n] = isValidRow[i][n] = isValidNine[temp][n] = false;
if (isSuccess)
return;
}
}
}
}
private void init(char[][] board, int i, int j) {
isValidRow[i][board[i][j] - '1'] = true;
isValidColumn[j][board[i][j] - '1'] = true;
isValidNine[i / 3 * 3 + j / 3][board[i][j] - '1'] = true;
}
}
/*
* 36 ms
* 18.91%
*/
static class Solution2 {
public void solveSudoku(char[][] board) {
solveSudoku2(board);
}
public boolean solveSudoku2(char[][] board) {
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
for (int k = 0; k < 9; ++k) {
board[i][j] = (char) ('1' + k);
if (isValid(board, i, j) && solveSudoku2(board))
return true;
board[i][j] = '.';
}
return false;
}
}
return true;
}
private boolean isValid(char[][] board, int x, int y) {
int i, j;
for (i = 0; i < 9; i++)
if (i != x && board[i][y] == board[x][y])
return false;
for (j = 0; j < 9; j++)
if (j != y && board[x][j] == board[x][y])
return false;
for (i = 3 * (x / 3); i < 3 * (x / 3 + 1); i++)
for (j = 3 * (y / 3); j < 3 * (y / 3 + 1); j++)
if ((i != x || j != y) && board[i][j] == board[x][y])
return false;
return true;
}
}
}
C Solution: github
/*
url: leetcode.com/problems/sudoku-solver/
19ms 11.43%
*/
#include <stdio.h>
#include <stdlib.h>
#define bool int
int isValid(char** b, int x, int y) {
int i = 0, j = 0, k = 0;
for (k = 0; k < 9; k ++) {
if (k != x && b[k][y] == b[x][y])
return 0;
if (k != y && b[x][k] == b[x][y])
return 0;
i = (x / 3) * 3 + k / 3;
j = (y / 3) * 3 + k % 3;
if ((i != x || j != y) && b[i][j] == b[x][y])
return 0;
}
return 1;
}
bool solveSudoku2(char** b) {
int i = 0, j = 0, k = 0;
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j) {
if (b[i][j] != '.') continue;
for (k = 0; k < 9; ++k) {
b[i][j] = (char) ('1' + k);
if (isValid(b, i, j) && solveSudoku2(b))
return 1;
b[i][j] = '.';
}
return 0;
}
return 1;
}
void solveSudoku(char** b, int rs, int cs) {
int val = solveSudoku2(b);
printf("answer is %d\r\n", val);
}
char* setChar(char* src, int n) {
int i = 0;
char* dst = (char*)malloc(sizeof(char) * (n + 1));
for (i = 0; i <= n; i ++)
*(dst + i) = *(src + i);
return dst;
}
int main() {
char** b = (char **) malloc(sizeof(char *) * 9);
char* t = NULL, * tt = NULL;
int rs = 9, cs = 9, i = 0, j = 0;
b[0] = setChar("..9748...", 9);
b[1] = setChar("7........", 9);
b[2] = setChar(".2.1.9...", 9);
b[3] = setChar("..7...24.", 9);
b[4] = setChar(".64.1.59.", 9);
b[5] = setChar(".98...3..", 9);
b[6] = setChar("...8.3.2.", 9);
b[7] = setChar("........6", 9);
b[8] = setChar("...2759..", 9);
solveSudoku(b, rs, cs);
for (i = 0; i < 9; i ++) {
for (j = 0; j < 9; j ++) {
printf("%c ", b[i][j]);
}
printf("\r\n");
}
for (i = 0; i < 9; i ++)
free(*(b + i));
free(b);
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/sudoku-solver/
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年4月5日
@details: Solution: 1709ms 12.51%
'''
from jinja2._compat import unichr
class Solution(object):
def isValid(self, b, x, y):
x_base, y_base = (x // 3) * 3, (y // 3) * 3
for k in range(9):
if x != k and b[x][y]==b[k][y]:
return False
if y != k and b[x][y]==b[x][k]:
return False
new_x, new_y = x_base+(k // 3), y_base+(k % 3)
if new_x != x and new_y != y and b[x][y] == b[new_x][new_y]:
return False
return True
def solve(self, b):
for x in range(9):
for y in range(9):
if b[x][y] != '.':continue
for k in range(9):
b[x][y]=unichr(ord('1')+k)
if self.isValid(b, x, y)\
and self.solve(b):
return True
b[x][y] = '.'
return False
return True
def solveSudoku(self, b):
"""
:type b: List[List[str]]
:rtype: void Do not return anything, modify b in-place instead.
"""
self.solve(b)
if __name__ == "__main__":
b=[list("..9748..."),\
list("7........"),\
list(".2.1.9..."),\
list("..7...24."),\
list(".64.1.59."),\
list(".98...3.."),\
list("...8.3.2."),\
list("........6"),\
list("...2759..")]
Solution().solve(b)
print(b)