Valid Sudoku
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'
.
A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
暴力解法,一行一行的看,一列一列的看,一个一个方格的看,
代码如下:
class Solution { public: bool isValidCell(vector<vector<char> > &board, int a, int b) { vector<bool> flag(9, false); int idx; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { idx = board[a + i][b + j] - '0'; if (idx > 0 && idx <= 9 && !flag[idx]) flag[idx] = true; else if (idx > 0 && idx <= 9 && flag[idx]) return false; } } return true; } bool isValidRow(vector<vector<char> > &board, int a) { vector<bool> flag(9, false); int idx; for (int j = 0; j < 9; ++j) { idx = board[a][j] - '0'; if (idx > 0 && idx <= 9 && !flag[idx]) flag[idx] = true; else if (idx > 0 && idx <= 9 && flag[idx]) return false; } return true; } bool isValidCol(vector<vector<char> > &board, int b) { vector<bool> flag(9, false); int idx; for (int i = 0; i < 9; ++i) { idx = board[i][b] - '0'; if (idx > 0 && idx <= 9 && !flag[idx]) flag[idx] = true; else if (idx > 0 && idx <= 9 && flag[idx]) return false; } return true; } bool isValidSudoku(vector<vector<char> > &board) { for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (!isValidCell(board, 3 * i, 3 * j)) return false; } } for (int i = 0; i < 9; ++i) { if (!isValidRow(board, i)) return false; } for (int j = 0; j < 9; ++j) { if (!isValidCol(board, j)) return false; } return true; } };
一种简介的解法(还没认真看,可能牵扯到一些数学):
class Solution { public: bool isValidSudoku(vector<vector<char> > &board) { vector<vector<bool>> rows(9, vector<bool>(9,false)); vector<vector<bool>> cols(9, vector<bool>(9,false)); vector<vector<bool>> blocks(9, vector<bool>(9,false)); for(int i = 0; i < 9; i++) for(int j = 0; j < 9; j++) { if(board[i][j] == '.')continue; int num = board[i][j] - '1'; if(rows[i][num] || cols[j][num] || blocks[i - i%3 + j/3][num]) return false; rows[i][num] = cols[j][num] = blocks[i - i%3 + j/3][num] = true; } return true; } };
Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
很多题乍一看很难,是因为思路不清晰,只要思路清晰了,还是很简单的。
思路:
首先,每一行每一列的数字不能重合,其次把81个格子分成9个小格子,每一个格子里面的数字不能重合。
转:http://www.cnblogs.com/ganganloveu/p/3828401.html
这题跟N-Queens是一个套路,回溯法尝试所有解。
需要注意的区别是:
本题找到解的处理是return true,因此返回值为bool
N-Queen找到解的处理是保存解,因此返回值为void
对于每个空位'.',遍历1~9,check合理之后往下一个位置递归。
由于这里路径尝试本质上是有序的,即1~9逐个尝试,因此无需额外设置状态位记录已经尝试过的方向。
注意:只有正确达到最终81位置(即成功填充)的填充结果才可以返回,若不然,将会得到错误的填充。
因此辅助函数solve需要设为bool而不是void
class Solution { public: void solveSudoku(vector<vector<char> > &board) { solve(board, 0); } bool solve(vector<vector<char> > &board, int position) { if(position == 81) return true; int row = position / 9; int col = position % 9; if(board[row][col] == '.') { for(int i = 1; i <= 9; i ++) {//try each digit board[row][col] = i + '0'; if(check(board, position)) if(solve(board, position + 1)) //only return valid filling return true; board[row][col] = '.'; } } else { if(solve(board, position + 1)) //only return valid filling return true; } return false; } bool check(vector<vector<char> > &board, int position) { int row = position / 9; int col = position % 9; int gid; if(row >= 0 && row <= 2) { if(col >= 0 && col <= 2) gid = 0; else if(col >= 3 && col <= 5) gid = 1; else gid = 2; } else if(row >= 3 && row <= 5) { if(col >= 0 && col <= 2) gid = 3; else if(col >= 3 && col <= 5) gid = 4; else gid = 5; } else { if(col >= 0 && col <= 2) gid = 6; else if(col >= 3 && col <= 5) gid = 7; else gid = 8; } //check row, col, subgrid for(int i = 0; i < 9; i ++) { //check row if(i != col && board[row][i] == board[row][col]) return false; //check col if(i != row && board[i][col] == board[row][col]) return false; //check subgrid int r = gid/3*3+i/3; int c = gid%3*3+i%3; if((r != row || c != col) && board[r][c] == board[row][col]) return false; } return true; } };