Leetcode-36. 有效的數獨
阿新 • • 發佈:2020-11-16
36. 有效的數獨
判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。
- 數字
1-9
在每一行只能出現一次。 - 數字
1-9
在每一列只能出現一次。 - 數字
1-9
在每一個以粗實線分隔的3x3
宮內只能出現一次。
數獨部分空格內已填入了數字,空白格用 '.'
表示。
簡單的想法就是按行,列,塊三次遍歷陣列,確保有效。進一步可以一次迭代就可以,每次迭代時記錄下行,列,塊的已經看到的元素,(可以使用set記錄)。然後遍歷的時候如果看到之前的記錄中有當前的數,就無效。需要注意的時,假設順序為從左到右,從上到下,那麼
- 第
i
行第j
列的數就位於第(i/3)*3+j/3
- 第
i
塊第j
個數的行和列就分別為((i/3)*3+j/3, (i%3)*3+j%3)
。
class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { vector<set<char>> row(9); vector<set<char>> col(9); // 方塊 for (int i = 0; i < 9; ++i) { set<char> num; for (int j = 0; j < 9; ++j) { if (board[x][y] != '.') { // i是第幾個塊,j是塊內第幾個數, x是第幾行,y是第幾列 int x = (i / 3) * 3 + j / 3; int y = (i % 3) * 3 + j % 3; if (row[x].find(board[x][y]) == row[x].end()) { row[x].insert(board[x][y]); } else { return false; } if (col[y].find(board[x][y]) == col[y].end()) { col[y].insert(board[x][y]); } else { return false; } if (num.find(board[x][y]) == num.end()) { num.insert(board[x][y]); } else { return false; } } } } return true; } };
這裡面比較大的時間損耗在於set的查詢,可以用一個二維陣列來代替,比如建立一個二維陣列row,第i行,第j列表示數獨內第i行存不存在j+1這個數。這樣會比較快。
class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { int row[9][9] = {0}; int col[9][9] = {0}; int num[9][9] = {0}; for (int i = 0; i < 9; ++i) { for (int j = 0; j < 9; ++j) { // i是第幾行,j是第幾列 if (board[i][j] != '.') { int cur_num = board[i][j] - '1'; if (row[i][cur_num]) { return false; } if (col[j][cur_num]) { return false; } int block = (i / 3) * 3 + j / 3; if (num[block][cur_num]) { return false; } row[i][cur_num] = 1; col[j][cur_num] = 1; num[block][cur_num] = 1; } } } return true; } };
但在Leetcode上測試好像也沒快多少~_~。