37. 解数独
解题思路
-
通过solveSudoku方法开始求解数独问题,然后调用backtrack方法进行递归回溯搜索。backtrack方法通过两个参数i和j来确定当前搜索的位置。
-
在backtrack方法中,首先检查当前位置是否超出了数独的边界,若超出,则表示已经搜索完整个数独,返回true。然后检查当前位置是否已经填入数字,若已填入,则跳到下一个位置进行搜索。接着,遍历尝试填入数字1到9,若遇到不合法的数字,则跳过,继续尝试下一个数字。若尝试填入的数字是合法的,则将该数字填入当前位置,并继续递归地向下搜索。若搜索到底部并找到解,则返回true;若没有找到解,则撤销当前选择的数字,回溯到上一步。若遍历完所有数字仍未找到解,则返回false。
-
isValid方法用于检查当前填入的数字是否符合数独的规则。它检查当前位置所在的行、列以及对应的3×3方格是否存在重复的数字。若存在重复,则返回false;否则返回true。
class Solution {public void solveSudoku(char[][] board) {backtrack(board,0,0);}boolean backtrack(char[][] board,int i,int j){int m = 9;int n = 9;if(j == n){// 穷举到最后一列 直接换行开始return backtrack(board,i + 1,0);}if(i == m){return true;// 找到一个可行解}// 如果该位置是预设的数字 if(board[i][j] != '.'){return backtrack(board,i,j + 1);}for(char ch = '1'; ch <= '9'; ch++){// 遇到不合法的数字 直接跳过if(!isValid(board,i,j,ch)){continue;}board[i][j] = ch;// 进行选择if(backtrack(board,i, j+ 1)){return true;}board[i][j] = '.';// 撤销选择}return false;}boolean isValid(char[][] board,int r,int c,char n){// 判断字符是否可以填入for(int i = 0; i < 9; i++){// 判断第r行是否有重复字符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;}
}