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; } }