labuladong讲解
37. 解数独(困难)
题目:
数独部分空格内已填入了数字,空白格用 '.' 表示。
思路:
输入是一个9x9的棋盘,空白格子用点号字符
.
表示,算法需要在原地修改棋盘,将空白格子填上数字,得到一个可行解。当 col 到达超过每一行的最后一个索引时,转为增加 row 开始穷举下一行,并且在穷举之前添加一个判断,跳过不满足条件的数字
当
row == m
的时候就说明穷举完了最后一行,完成了所有的穷举,就是 base case。class Solution { public: void solveSudoku(vector<vector<char>>& board) { backtrack(board,0,0); } bool backtrack(vector<vector<char>>& board, int row, int col){ int m=9,n=9; if(col==n){ // 穷举到最后一列的话就换到下一行重新开始。 return backtrack(board,row+1,0); } if(row==m){ // 找到一个可行解,触发 base case return true; } if(board[row][col]!='.'){ // 如果有预设数字,不用我们穷举 return backtrack(board,row,col+1); } for(char ch='1';ch<='9';ch++){ // 如果遇到不合法的数字,就跳过 if(!isValid(board,row,col,ch)){ continue; } board[row][col]=ch; // 如果找到一个可行解,立即结束 if(backtrack(board,row,col+1)){ return true; } board[row][col]='.'; } // 穷举完 1~9,依然没有找到可行解,此路不通 return false; } // 判断 board[r][c] 是否可以填入 ch bool isValid(vector<vector<char>>& board,int row,int col,char ch){ for(int i=0;i<9;++i){ // 判断行是否存在重复 if(board[row][i]==ch){ return false; } // 判断列是否存在重复 if(board[i][col]==ch){ return false; } // 判断 3 x 3 方框是否存在重复 int suqare_row=(row/3)*3+i/3; int suqare_col=(col/3)*3+i%3; if(board[suqare_row][suqare_col]==ch){ return false; } } return true; } };