题目:
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
- Each of the digits
1-9
must occur exactly once in each row. - Each of the digits
1-9
must occur exactly once in each column. - Each of the the digits
1-9
must occur exactly once in each of the 93x3
sub-boxes of the grid.
Empty cells are indicated by the character '.'
.
A sudoku puzzle...
...and its solution numbers marked in red.
Note:
- The given board contain only digits
1-9
and the character'.'
. - You may assume that the given Sudoku puzzle will have a single unique solution.
- The given board size is always
9x9
.
分析:
数独应该很多人都有玩过,其规则是每列,每行,每个九宫格数字都是1-9,且没有重复的。
那么这道题的解法就是在数独中依次添加1-9,同时判断是否符合条件,如果不符合就回溯,符合条件就在下个格子填数字。可以维护几个数组,用来标记哪行哪列哪个九宫格中的数字是否被使用过。
程序:
C++
class Solution { public: void solveSudoku(vector<vector<char>>& board) { cols = vector<vector<int>>(9, vector<int>(10, 0)); rows = vector<vector<int>>(9, vector<int>(10, 0)); //boxs index // 0, 1, 2 // 3, 4, 5 // 6, 7, 8 boxs = vector<vector<int>>(9, vector<int>(10, 0)); for(int i = 0; i < board.size(); ++i){ for(int j = 0; j < board[i].size(); ++j){ if(board[i][j] != '.'){ int k = board[i][j] - '0'; rows[i][k] = 1; cols[j][k] = 1; int bx = i / 3; int by = j / 3; boxs[bx + by * 3][k] = 1; } } } dfs(board, 0, 0); } private: vector<vector<int>> cols, rows, boxs; bool dfs(vector<vector<char>>& board, int r, int c){ if(r == 9) return true; int nextR = r; int nextC = (c + 1) % 9; if(nextC == 0) nextR = r + 1; if(board[r][c] != '.') return dfs(board, nextR, nextC); for(int i = 1; i <= 9; ++i){ int bx = r / 3; int by = c / 3; int boxIndex = bx + by * 3; if(!rows[r][i] && !cols[c][i] && !boxs[boxIndex][i]){ rows[r][i] = 1; cols[c][i] = 1; boxs[boxIndex][i] = 1; board[r][c] = i + '0'; if(dfs(board, nextR, nextC)) return true; rows[r][i] = 0; cols[c][i] = 0; boxs[boxIndex][i] = 0; board[r][c] = '.'; } } return false; } };
Java
class Solution { public void solveSudoku(char[][] board) { rows = new int[9][10]; cols = new int[9][10]; boxs = new int[9][10]; for(int i = 0; i < board.length; ++i){ for(int j = 0; j < board[i].length; ++j){ if(board[i][j] != '.'){ int k = board[i][j] - '0'; rows[i][k] = 1; cols[j][k] = 1; int bx = i / 3; int by = j / 3; boxs[bx + by * 3][k] = 1; } } } dfs(board, 0, 0); } private boolean dfs(char[][] board, int r, int c){ if(r == 9) return true; int nextR = r; int nextC = (c + 1) % 9; if(nextC == 0) nextR = r + 1; if(board[r][c] != '.') return dfs(board, nextR, nextC); for(int i = 1; i <= 9; ++i){ int bx = r / 3; int by = c / 3; int boxIndex = bx + by * 3; if(rows[r][i] == 0 && cols[c][i] == 0 && boxs[boxIndex][i] == 0){ rows[r][i] = 1; cols[c][i] = 1; boxs[boxIndex][i] = 1; board[r][c] = (char)(i + '0'); if(dfs(board, nextR, nextC)) return true; rows[r][i] = 0; cols[c][i] = 0; boxs[boxIndex][i] = 0; board[r][c] = '.'; } } return false; } private int[][] rows; private int[][] cols; private int[][] boxs; }