【三次過】Lintcode 389. 判斷數獨是否合法
請判定一個數獨是否有效。
該數獨可能只填充了部分數字,其中缺少的數字用 .
表示。
樣例
The following partially filed sudoku is valid.
解題思路:
驗證數獨是否有效,就三個要求:
1.數字1-9在每一行最多隻能出現一次
2.數字1-9在每一列最多隻能出現一次
3.數字1-9在每一個3*3九宮格內最多隻能出現一次
出現有次數的題目,一般採用雜湊表,所以我們只需要檢查每一行,每一列,每個九宮格中數字出現的次數即可,分別用三個雜湊表儲存。
難點在於表示第i個九宮格每個格點的座標。
觀察行號規律:
第0個九宮格:000111222; 第1個九宮格:000111222; 第2個九宮格:000111222;
第3個九宮格:333444555; 第4個九宮格:333444555; 第5個九宮格:333444555;
第6個九宮格:666777888; 第7個九宮格:666777888; 第8個九宮格:666777888;
可見對於每三個九宮格行號增3;對於單個九宮格,每三個格點行號增1。
因此第i個九宮格的第j個格點的行號可表示為i/3*3+j/3
觀察列號規律:
第0個九宮格:012012012; 第1個九宮格:345345345; 第2個九宮格:678678678;
第3個九宮格:012012012; 第4個九宮格:345345345; 第5個九宮格:678678678;
第6個九宮格:012012012; 第7個九宮格:345345345; 第8個九宮格:678678678;
可見對於下個九宮格列號增3,迴圈週期為3;對於單個九宮格,每個格點行號增1,週期也為3。
週期的數學表示就是取模運算mod。
因此第i個九宮格的第j個格點的列號可表示為i%3*3+j%3
class Solution { public: /** * @param board: the board * @return: whether the Sudoku is valid */ bool isValidSudoku(vector<vector<char>> &board) { // write your code here for(int i=0;i<board.size();i++) { unordered_map<char,int> m_row; unordered_map<char,int> m_col; unordered_map<char,int> m_san; for(int j=0;j<board[i].size();j++) { if(board[i][j] != '.' && ++m_row[board[i][j]] > 1)//檢查每一行的元素是否重複 return false; if(board[j][i] != '.' && ++m_col[board[j][i]] > 1)//檢查每一列的元素是否重複 return false; if(board[i/3*3+j/3][i%3*3+j%3] != '.' && ++m_san[board[i/3*3+j/3][i%3*3+j%3]] > 1)//檢查每個九宮格的元素是否重複 return false; } } return true; } };
如果還是不能理解上面九宮格的下標演算法,可以直接重新遍歷即可,如下:
class Solution {
public:
/**
* @param board: the board
* @return: whether the Sudoku is valid
*/
bool isValidSudoku(vector<vector<char>> &board)
{
// write your code here
for(int i=0;i<board.size();i++)
{
unordered_map<char,int> m_row;
unordered_map<char,int> m_col;
for(int j=0;j<board[i].size();j++)
{
if(board[i][j] != '.' && ++m_row[board[i][j]] > 1)//檢查每一行的元素是否重複
return false;
if(board[j][i] != '.' && ++m_col[board[j][i]] > 1)//檢查每一列的元素是否重複
return false;
}
}
for(int i=0;i<board.size();i+=3)
{
for(int j=0;j<board[i].size();j+=3)
{
unordered_map<char,int> m_san;
for(int row=i;row<i+3;row++)
for(int col=j;col<j+3;col++)
if(board[row][col] != '.'
&& ++m_san[board[row][col]] > 1)//檢查每個九宮格的元素是否重複
return false;
}
}
return true;
}
};