回溯算法一般用于需要穷举中间状态以找到最终结果状态的情形,通常搭配DFS使用,假设中间状态成立,推出结果后判断是否符合结果,否则将状态复原,寻找下一个可能结果。
其实就是DFS+回溯,贴一下代码。
环境
- Language: Java SE(jdk 1.8.0_211)
- JVM: Java HotSpot 64-Bit Server VM)
- IDE:IntelliJ IDEA(2019.1.4)
- Character set: GBK
代码:
package homework;
import java.util.Scanner;
/**
* @author zhongteng <qq754159742@outlook.com>
*/
/*
回溯实现数独
*/
public class Sudoku {
private int[][] matrix;
private Sudoku(int[][] matrix) {
this.matrix = matrix;
}
/**
* backTrace
* @param row 行
* @param col 列
*/
private void backTrace(int row, int col) {
// return if cal is done
if(col==9) {
if(row==8) {
System.out.println("success to get result!:");
for(int r=0; r<9; r++) {
for(int c=0; c<9; c++) {
System.out.print(matrix[r][c] + " ");
}
System.out.println();
}
return;
}
else {
row++;
col=0;
}
}
if(matrix[row][col] == 0) {
for(int value=1; value<10; value++) {
if(checkIfRepeat(row, col, value)) {
matrix[row][col] = value;
backTrace(row, col+1);
matrix[row][col] = 0;
}
}
} else {
backTrace(row, col+1);
}
}
/**
* 判重
* @param row 行
* @param col 列
* @param value 需判重值
* @return 重复与否
*/
private boolean checkIfRepeat(int row, int col, int value) {
for(int i=0; i<9; i++) {
if(matrix[row][i] == value || matrix[i][col] == value) {
return false;
}
}
int subMatrixRow = row/3;
int subMatrixCol = col/3;
for(int r=0; r<3; r++) {
for(int c=0; c<3; c++) {
if(matrix[subMatrixRow*3 + r][subMatrixCol*3 + c] == value) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[][] matrix = new int[10][];
for(int i=0; i<9; i++) {
matrix[i] = new int[10];
}
System.out.println("pls input a sudoku of 9 cols & 9 rows, number range[0-9], 0 represents empty value, split number in a row with space :");
System.out.println("usecase:");
String str = "8 0 0 0 0 0 0 0 0\n" +
"0 0 3 6 0 0 0 0 0\n" +
"0 7 0 0 9 0 2 0 0\n" +
"0 5 0 0 0 7 0 0 0\n" +
"0 0 0 0 4 5 7 0 0\n" +
"0 0 0 1 0 0 0 3 0\n" +
"0 0 1 0 0 0 0 6 8\n" +
"0 0 8 5 0 0 0 1 0\n" +
"0 9 0 0 0 0 4 0 0\n";
System.out.println(str);
System.out.println("copy the usecase and click enter to see the result.");
for(int row=0; row<9; row++) {
String rowStr = sc.nextLine();
if(rowStr.length() > 0) {
String[] rowStrSplit = rowStr.split(" ");
if(rowStrSplit.length != 9) {
System.out.println("error input col count.");
return;
}
for(int col=0; col<9; col++) {
int inputValue = Integer.parseInt(rowStrSplit[col]);
if(inputValue < 0 || inputValue > 9) {
System.out.println("error input number range.");
return;
}
matrix[row][col] = inputValue;
}
} else {
System.out.println("error input col.");
return;
}
}
Sudoku sudoku = new Sudoku(matrix);
Long start = System.currentTimeMillis();
sudoku.backTrace(0, 0);
Long end = System.currentTimeMillis();
System.out.println("cost time: " + (end - start) + "ms");
}
}
结果: