37. 解数独
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
一个数独。
答案被标成红色。
提示:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
解题思路
利用回溯算法的思想:先遍历每行,行完了再遍历下一行
如果到最后一列,则换下一行
如果到最后一行,则说明找到了可信解,返回true
如果该位置已经有值,则跳出
然后遍历1-9九个选择
判断当前字符是否合法,合法则先选,再递归,再撤销选择
合法性判断:同行、同列或者3*3内没有
class Solution {
char[] nums=new char[]{'1','2','3','4','5','6','7','8','9'};
public void solveSudoku(char[][] board) {
backtrack(board,0,0);
}
public boolean backtrack(char[][] board,int i,int j){
if(i>=board.length) return true;
//换下一行
if(j>=board[0].length) return backtrack(board,i+1,0);
//有数字则跳过
if(board[i][j] != '.') return backtrack(board,i,j+1);
for(char ch:nums){
if(!isVaild(board,i,j,ch)){
continue;//不合法则继续
}
board[i][j]=ch;
if(backtrack(board,i,j+1)){
return true;
}
board[i][j]='.';
}
return false;
}
public boolean isVaild(char[][] board,int r,int c,char n){
for (int i = 0; i < 9; i++) {
// 判断行是否存在重复
if (board[r][i] == n) return false;
// 判断列是否存在重复
if (board[i][c] == n) return false;
// 判断 3 x 3 方框是否存在重复
if (board[(r/3)*3 + i/3][(c/3)*3 + i%3] == n)
return false;
}
return true;
}
}
京公网安备 11010502036488号