[LeetCode] 37. 解數獨
阿新 • • 發佈:2019-05-09
pri 序列 列塊 找到 解法 arraylist thumb 進步 檢查 到
題目鏈接 : https://leetcode-cn.com/problems/sudoku-solver/
題目描述:
編寫一個程序,通過已填充的空格來解決數獨問題。
一個數獨的解法需遵循如下規則:
數字
1-9
在每一行只能出現一次。數字
1-9
在每一列只能出現一次。數字
1-9
在每一個以粗實線分隔的3x3
宮內只能出現一次。空白格用
‘.‘
表示。
示例:
一個數獨。
答案被標成紅色。
Note:
- 給定的數獨序列只包含數字
1-9
和字符‘.‘
。 - 你可以假設給定的數獨只有唯一解。
- 給定數獨永遠是
9x9
形式的。
思路:
思路1:
用一句話解釋:不停的試數
詳細解釋:對於空位置,從數字1
9
去試數,
如何判斷這個是否是這個數,就是通過數獨的規則,行列塊出現相同的數字就不行.
所以,我們就可以通過回溯方法去解決,詳細解釋寫在代碼裏!
因為我不太擅長 Java
只能通過與 Python
方式寫出來,如果有更好的方式可以提供給我,謝謝 !
思路2:
有種在線方法,沒看懂,留個坑
未完待續...
關註我的知乎專欄,了解更多的解題技巧,大家共同進步!
代碼:
class Solution: def solveSudoku(self, board: List[List[str]]) -> None: """ Do not return anything, modify board in-place instead. """ # 把所有沒填數字的位置找到 all_points = [] for i in range(9): for j in range(9): if board[i][j] == ".": all_points.append([i, j]) # check函數是為了檢查是否在point位置k是合適的 def check(point, k): row_i = point[0] col_j = point[1] for i in range(9): # 檢查 行 if i != row_i and board[i][col_j] == k: return False # 檢查 列 if i != col_j and board[row_i][i] == k: return False # 檢查塊 for i in range(row_i//3*3 , row_i//3*3+3): for j in range(col_j//3*3, col_j//3*3+3): if i != row_i and j != col_j and board[i][j] == k: return False return True def backtrack(i): # 回溯終止條件 if i == len(all_points): return True for j in range(1, 10): # 檢查是否合適 if check(all_points[i],str(j)): # 合適就把位置改過來 board[all_points[i][0]][all_points[i][1]] = str(j) if backtrack(i+1): # 回溯下一個點 return True board[all_points[i][0]][all_points[i][1]] = "."# 不成功把原來改回來 return False backtrack(0)
class Solution { public void solveSudoku(char[][] board) { if (board == null || board.length == 0) return; List<int[]> all_points = new ArrayList<>(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] == '.') all_points.add(new int[]{i, j}); } } backtrack(0, all_points, board); } private boolean backtrack(int i, List<int[]> all_points, char[][] board) { if (i == all_points.size()) return true; for (char c = '1'; c <= '9'; c++) { if (check(all_points.get(i), c, board)) { board[all_points.get(i)[0]][all_points.get(i)[1]] = c; if (backtrack(i + 1, all_points, board)) return true; board[all_points.get(i)[0]][all_points.get(i)[1]] = '.'; } } return false; } private boolean check(int[] ints, char c, char[][] board) { int row_i = ints[0]; int col_j = ints[1]; for (int i = 0; i < 9; i++) { if (i != row_i && board[i][col_j] == c) return false; if (i != col_j && board[row_i][i] == c) return false; } for (int i = row_i / 3 * 3; i < row_i / 3 * 3 + 3; i++) { for (int j = col_j / 3 * 3; j < col_j / 3 * 3 + 3; j++) { if (i != row_i && j != col_j && board[i][j] == c) return false; } } return true; } }
[LeetCode] 37. 解數獨