Leecode no.37 解数独

package leecode;

import java.util.ArrayList;
import java.util.List;

/**
*编写一个程序,通过填充空格来解决数独问题。
*
* 一个数独的解法需遵循如下规则:
*
* 数字 1-9 在每一行只能出现一次。
* 数字 1-9 在每一列只能出现一次。
* 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
* 空白格用 '.' 表示。
*
* 给定的数独序列只包含数字 1-9 和字符 '.' 。
* 你可以假设给定的数独只有唯一解。
* 给定数独永远是 9x9 形式的。
*/
public class SolveSudoku {

char[][] result;

public void solveSudoku(char[][] board) {
if(board == null){
return;
}
result = board;

tryInput(0,0);

}

/**
* 尝试输入一个位置的元素,看看有没有冲突,如果没有冲突就递归输入下一个元素,
* 如果冲突会滚回来元素变动
* @param indexX 要输入元素的横坐标 x
* @param indexY 要输入元素的纵坐标 y
* @return 如果下一个的元素没有冲突则返回true
*/
public boolean tryInput(int indexX, int indexY){
//此时已经到头了 全输入满了
if(indexY == 9){
return true;
}
//下一个输入的结果是否成功
boolean nextRes;
//当前元素可能输入的值
int code = 1;

if(result[indexY][indexX] == '.'){
//尝试输入本次元素1 - 9,如果成功就递归去输入下一个元素,
// 如果下一个元素输入不成功本次元素+1再试,试到头了 返回false
while(code < 10){
//判断当前元素输入code是否会引起冲突
if(!isConflict(indexX, indexY, String.valueOf(code).charAt(0))){
result[indexY][indexX] = String.valueOf(code).charAt(0);
nextRes = tryInput(indexX == 8 ? 0 : indexX+1, indexX == 8 ? indexY+1 : indexY);
if(nextRes){
return nextRes;
}
//重置当前元素
result[indexY][indexX] = '.';
}
code++;
}

}else{
//如果当前元素是固定字的情况
return tryInput(indexX == 8 ? 0 : indexX+1, indexX == 8 ? indexY+1 : indexY);
}
return false;
}

/**
* 判断某元素在某个位置上是否存在冲突
* @param indexX
* @param indexY
* @param code
* @return
*/
public boolean isConflict(int indexX, int indexY, char code){
return lineConflict(indexX,indexY,code) || rowConflict(indexX, indexY, code) || ninePointsConflict(indexX, indexY, code);

}


/**
* 所在行是否冲突
* @return
*/
public boolean lineConflict(int indexX, int indexY, char code){
char[] chars = result[indexY];
for(int j = 0; j < result.length; j++){
if(code == chars[j]){
return true;
}
}
return false;
}

/**
* 所在列是否冲突
* @return
*/
public boolean rowConflict(int indexX, int indexY, char code){
for(int i = 0; i < result.length; i++){
if(code == result[i][indexX]){
return true;
}
}
return false;
}

/**
* 所在3*3宫格是否冲突
* @return
*/
public boolean ninePointsConflict(int indexX, int indexY, char code){
int x,y;

if(indexX <= 2){
x = 0;
}else if(indexX >= 6){
x = 6;
}else{
x = 3;
}
if(indexY <= 2){
y = 0;
}else if(indexY >= 6){
y = 6;
}else{
y = 3;
}

List<Character> ninePoints = new ArrayList<>();
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
ninePoints.add(result[y][x+j]);
}
y++;
}

return ninePoints.contains(code);
}

/**
* 打印
*/
public void printResult(){
for(int i = 0; i < 9; i++){

for(int j = 0; j < 9; j++){
System.out.print(result[i][j]+" ");
}
System.out.println();
}


}

public static void main(String[] args) {
char[][] test =
{{'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'}};

SolveSudoku solveSudoku = new SolveSudoku();
solveSudoku.solveSudoku(test);
solveSudoku.printResult();


}

}
原文地址:https://www.cnblogs.com/ttaall/p/14634380.html