【Valid Sudoku】cpp
题目:
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 isValidSudoku(std::vector<std::vector<char> > &board) { int len = board.size(); if (len != 9) return false; bool row_check[9]; bool col_check[9]; bool subBox_check[9]; for (int row = 0; row < len; ++row) { std::fill(row_check, row_check+9, false); std::fill(col_check, col_check+9, false); std::fill(subBox_check, subBox_check+9, false); for (int col = 0; col < len; ++col) { if (!Solution::if_valid(board, row, col, row_check)){ return false; } if (!Solution::if_valid(board, col, row, col_check)){ return false; } if (!Solution::if_valid(board, 3*(row/3)+col/3, 3*(row%3)+col%3, subBox_check)){ return false; } } } return true; } static bool if_valid(std::vector<std::vector<char> > &board, int x, int y, bool (&some_check)[9]) { if (board[x][y]=='.'){ return true; } else{ if (some_check[board[x][y]-'1']){ return false; } else{ some_check[board[x][y]-'1'] = true; return true; } } return false; } };
Tips:
1. 整体逻辑按照数独的要求走:
a. 判断同一行
b. 判断同一列
c. 判断所在的sub box
2. 判断时主要利用的数据结构是类似HashSet,由于三类判断条件类似,因此单独提出来一段代码。
3. 一点儿技巧:这里时间复杂度没有什么可说的就是O(n²);可以做些文章的地方就是代码复杂度,如何遍历一次for..for...就判断完成全部的逻辑。
a. 这里的核心就在于数独是对称的矩阵,行列对称;因此,行列坐标互换就可以走一次for...for...就完成1.a和1.b的判断逻辑。
b. 这里还需要注意的是,for..for..中走完一列,则需要判断一个sub box是否valid;因此,需要将某一列的坐标映射到某个sub box上。搞清楚这一点就可以推理处坐标变换的公式。
4. 在离线测试的时候,处理c++的 vector 二维字符数组还是非常不熟练,由Python转成cpp刷题确实不太习惯。后面在刷到string的题目时候,再把这cpp这部分强化一下。
==================================================
第二次过这道题,第一次没有AC还是错在了sub matrix小方块的检验上面。
class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { for ( int i=0; i<board.size(); ++i ) { // check row vector<bool> row_used(9,false); for ( int j=0; j<board[i].size(); ++j ) { if ( board[i][j]!='.' ) { if ( row_used[board[i][j]-'1'] ) return false; row_used[board[i][j]-'1'] = true; } } // check col vector<bool> col_used(9,false); for ( int j=0; j<board.size(); ++j) { if ( board[j][i]!='.') { if ( col_used[board[j][i]-'1'] ) return false; col_used[board[j][i]-'1'] = true; } } // check sub matrix vector<bool> subm_used(9,false); for ( int j=0; j<board[i].size(); ++j ) { int row = 3*(i/3) + j/3; int col = 3*(i%3) + j%3; if ( board[row][col]!='.' ) { if ( subm_used[board[row][col]-'1'] ) return false; subm_used[board[row][col]-'1'] = true; } } } return true; } };
tips:
这个要记住了
row = 3*(i/3) + j/3
col = 3*(i%3) + j%3