1. 程式人生 > 實用技巧 >Leetcode-36. 有效的數獨

Leetcode-36. 有效的數獨

36. 有效的數獨

判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。

  1. 數字 1-9 在每一行只能出現一次。
  2. 數字 1-9 在每一列只能出現一次。
  3. 數字 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上測試好像也沒快多少~_~。