跳转至

36.Valid Sudoku

Tags: Medium Hash Table

Links: https://leetcode.com/problems/valid-sudoku/


Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:

  1. Each row must contain the digits 1-9 without repetition.
  2. Each column must contain the digits 1-9 without repetition.
  3. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.

img A partially filled sudoku which is valid.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

Example 1:

Input:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: true

Example 2:

Input:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: false
Explanation: Same as Example 1, except with the 5 in the top left corner being 
    modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.

Note:

  • A Sudoku board (partially filled) could be valid but is not necessarily solvable.
  • Only the filled cells need to be validated according to the mentioned rules.
  • The given board contain only digits 1-9 and the character '.'.
  • The given board size is always 9x9.

Answer:

//时间复杂度O(n), 空间复杂度O(1)
class Solution {
public:
    bool check(char ch, vector<bool> &used){
        if (ch == '.') return true;
        if (used[ch - '1']) return false;

        return used[ch - '1'] = true;
    }

    bool isValidSudoku(vector<vector<char>>& board) {
        vector<bool> used(9, false);

        for (int i = 0; i < 9; ++i){
            fill(used.begin(), used.end(), false);

            for (int j = 0; j < 9; ++j){ //检查行是否符合规则
                if(!check(board[i][j], used))
                    return false;
            }

            fill(used.begin(), used.end(), false);

            for (int j = 0; j < 9; ++j){ //检查列是否符合规则
                if(!check(board[j][i], used))
                    return false;
            }
        }

        for (int r = 0; r < 3; ++r){ //检查9个子格子
            for (int c = 0; c < 3; ++c){
                fill(used.begin(), used.end(), false);

                for (int i = r * 3; i < r*3 + 3; ++i){
                    for (int j = c * 3; j < c * 3 + 3; ++j)
                        if(!check(board[i][j], used))
                            return false;
                }
            }
        }

        return true;
    }
};
//运用unordered_set方法中的count
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        unordered_set<char> row, col;
        // Row - Col repetition check
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    if (!row.count(board[i][j])) row.insert(board[i][j]);
                    else return false;
                }
                if (board[j][i] != '.') {
                    if (!col.count(board[j][i])) col.insert(board[j][i]);
                    else return false;
                }
            }
            row.clear();
            col.clear();
        }

        //// 3x3 subgrid check
         row.clear();
         for (int i = 0; i < 9; i+=3) {
            for (int j = 0; j < 9; j+=3) {
                for (int k = i, kleft = 3; k < 9 && kleft>0; k++, kleft--) {
                    for (int m = j, mleft = 3; m < 9 && mleft>0; m++, mleft--) {
                        if(board[k][m] != '.') {
                            if (!row.count(board[k][m])) row.insert(board[k][m]);
                            else return false;
                        }
                    }
                }
                row.clear();
            }
         }
        return true;
    }
};