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 '.'
.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
问题分析:只是判断是否有重复的,不需要判断是否有解,相对简单;
1,三个维度的判重问题,行/列/sub九宫格,行和列比较容易定位,sub九宫格用(i/3, j/3)定位;
2,如何判重,就是1-9这九个数字判重,一个是bool数组,另一个方法是set;
【1】方法1,bool数组判重,三个二维bool数组,我发现用一个和两个数组都不行,因为2R1C(表示1) 和 1C2R(表示2)完全表示不同的数字。
不用哈希表,建立三个矩阵,分别对应行矩阵,列矩阵,分块矩阵。(为方便理解,位置和原来对应)
bool isValidSudoku(vector<vector<char>>& board) {
if(board.size()!=9) return false;
for(int i=0;i<0;i++){
if(board[i].size()!=9) return false;
}
const int ans=9;
bool rows[ans][ans]={false};
bool cols[ans][ans]={false};
bool area[ans][ans]={false};
for(int i=0;i<board.size();i++){
for(int j=0;j<board[i].size();j++){
if(board[i][j]=='.') continue;
int pos=board[i][j]-'0'-1;
//check rows
if(rows[i][pos]) return false;
rows[i][pos]=true;
//check cols
if(cols[pos][j]) return false;
cols[pos][j]=true;
//check area
int ref_row=i/3;//对应0,1,2
int ref_col=j/3;//对应0,1,2
//对应9个area区域
int area_i=pos/3+ref_row*3;
int area_j=pos%3+ref_col*3;
if(area[area_i][area_j]) return false;
area[area_i][area_j]=true;
}
}
return true;
}
【2】leetcode大牛的解法,用一个set,好聪明;只是时间稍微慢一点。
public class ValidSudokuSet {
/**
* Collect the set of things we see, encoded as strings. For example:
*
* '4' in row 7 is encoded as "7(4)".
* '4' in column 7 is encoded as "(4)7".
* '4' in the top-right block is encoded as "0(4)2".
* @param board
* @return
*/
// compared with boolean solution, coding is compact but programming is a little slower
public boolean isValidSudoku(char[][] board) {
Set<String> seen = new HashSet<>();
for(int i=0;i<board.length;i++){
for(int j=0;j<board.length;j++){
if(board[i][j] != '.'){
String b = "(" + board[i][j] + ")";
if(!seen.add(i+b)||!seen.add(b+j)||!seen.add(i/3+b+j/3)){
return false;
}
}
}
}
return true;
}
}