- 问题描述
- leetcode36 判断数独是否有效的升级版,给定一个未被完成的数独,要求完成。同样包含3个要求。
-
数字
1-9
在每一行只能出现一次 -
数字
1-9
在每一列只能出现一次数字1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
- 解决思路
- 肯定需要利用两层循环,对每个元素进行遍历。如果元素是 ' . ' 。则进行数字1-9中的某个数字的填充;
- 判断当前数字填充进去后,是否有效:
- 如果有效,则递归调用本身,进行进行下一个有效位置的填充
- 如果无效,则将当前位置的值改回去。
3. Java 代码如下:
1 class Solution { 2 public static void solveSudoku(char[][] board) { 3 if (board.length ==0 || board==null) { return; } 4 solver(board); 5 } 6 7 public boolean solver(char[][] board) { 8 for(int i=0; i<board.length; i++) { 9 for(int j=0; j<board.length; j++) { 10 if (board[i][j] == '.') { 11 for(char k='1'; k<='9'; k++) { 12 // 判断把 k 放到这里是否可以 13 if (isValid(board, i, j, k)) { 14 board[i][j] = k; 15 // 可以的话继续往下放,递归调用下去。如果发现不合适,则将[i][j]位置的值改回去 16 if (solver(board)) { 17 return true; 18 } else { 19 board[i][j] = '.'; 20 } 21 } 22 } 23 return false; 24 } 25 } 26 } 27 return true; 28 } 29 30 public boolean isValid(char[][] board, int row, int col, char c) { 31 for(int i=0; i<board.length; i++) { 32 // 行判重 33 if (board[row][i] == c) { return false; } 34 // 列判重 35 if (board[i][col] == c) { return false; } 36 // 小方格判重 37 //if (board[3*(row/3) + i/3][3*(col/3) + i%3] == c) return false; 38 } 39 // 小方格判重 40 for(int m=(row/3)*3; m<(row/3)*3+3; m++) { 41 for(int n = (col/3)*3; n<(col/3)*3 + 3; n++) { 42 if (board[m][n] == c) { return false; } 43 } 44 } 45 return true; 46 } 47 }
4. Python 代码如下:
1 class Solution: 2 def solveSudoku(self, board): 3 """ 4 :type board: List[List[str]] 5 :rtype: void Do not return anything, modify board in-place instead. 6 """ 7 if len(board) == 0: 8 return 9 self.bool_solve(board) 10 11 def bool_solve(self, board): 12 size_n = len(board) 13 for i in range(size_n): 14 for j in range(size_n): 15 if board[i][j] == ".": 16 for c in range(1,size_n+1): 17 if self.isvalid(i, j, "c"): 18 board[i][j] = "c" 19 if self.solveSudoku(board): 20 return True 21 else: 22 board[i][j] = "." 23 return False 24 return True 25 26 def isvalid(self, row, col, c): 27 for i in range(9): 28 if board[row][i] == c: 29 return False 30 if board[i][col] == c: 31 return False 32 if board[3*(row//3) + i//3][3*(col//3) + i%3] == c: 33 return False 34 return True
注意:Python中的字符和字符串都用双引号扩起来。Java中字符用单引号,字符串用双引号。