[Leetcode / hash table] valid Sudoku (hash maps are classified in the matrix)

Problem Description:

Determining a number of unique 9x9 is valid. Only in accordance with the following rules , to verify whether the numbers already filled can be effective.

  1. Numbers  1-9 appear only once in each row.
  2. Numbers  1-9 appear only once in each column.
  3. Digital  1-9 each separated by a thick solid line  3x3 can appear only once in utero.

The figure is the number of valid only a partially filled.

Sudoku part in the digital space has been filled, with a blank grid  '.' representation.

Example 1:

输入:
[
  ["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"]
]
输出: true

Example 2:


Description:

  • Only a valid number (portion has been filled) is not necessarily solvable.
  • According to the above rules only need to verify whether the figures have been filled can be effective.
  • Given the number of unique sequences contain only numbers  1-9 and characters  '.' .
  • Sudoku will always be given  9x9 form.

The basic idea:

Accordance with the subject they meet the three rules on the list: 3 * 3 matrix compliance. Rows that match, in line with the column.

We can build map to implement the relevant operation.

The key is our map classification labels, in the above rule, which corresponds to: number, line number matrix, the column number.

map the value I chose a set, to re-check .

We use (i / 3) * Rule 3 + j / 3 to determine the number of a matrix .

AC Code:

class Solution {
public:
    bool IsValidBlk(vector<vector<char>> &board) {
      // 第一个int是块的编号,第二个是hashset
      // 在这里我把整个矩阵分成了9个块
      map<int, unordered_set<int>> m;
      for (int i = 0; i < board.size(); ++i) {
        for (int j = 0; j < board[0].size(); ++j) {
          if (isdigit(board[i][j])) {
            if (m[(i / 3) * 3 + j / 3].count(board[i][j])) {
              return false;
            } else {
              m[(i / 3) * 3 + j / 3].insert(board[i][j]);
            }
          }
        } 
      }
      return true;
    }
  
    bool IsValidRow(vector<vector<char>> &board) {
      // 这里第一个参数是行数
      map<int, unordered_set<int>> m;
      for (int i = 0; i < board.size(); ++i) {
        for (int j = 0; j < board[0].size(); ++j) {
          if (isdigit(board[i][j])) {
            if (m[i].count(board[i][j])) {
              return false;
            } else {
              m[i].insert(board[i][j]);
            }
          }
        }
      }
      return true;
    }
    
    bool IsValidCol(vector<vector<char>> &board) {
      // 这里第一个参数是列数
      map<int, unordered_set<int>> m;
      for (int i = 0; i < board.size(); ++i) {
        for (int j = 0; j < board[0].size(); ++j) {
          if (isdigit(board[i][j])) {
            if (m[j].count(board[i][j])) {
              return false;
            } else {
              m[j].insert(board[i][j]);
            }
          }
        }
      }
      return true;
    }  
  
    bool isValidSudoku(vector<vector<char>>& board) {
      return IsValidBlk(board) && IsValidRow(board) && IsValidCol(board);  
    }
};

More simple idea:

We noticed that our hashmap the key is of type int, and we can use arrays instead - because the array is essentially to int array element type mappings.

At the same time, we can use the technique to achieve macro definition hasheset .

code show as below:

#define SET(num, flag) flag |= (1 << num)
#define CHECK(num, flag) flag & (1 << num)
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int row;
        int col[9] = {0}, matrix[9] = {0};
        for (int i = 0; i < 9; i++) {
            row = 0;
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') continue;
                int x = board[i][j] - '0';
                int m_idx = (i / 3) * 3 + j / 3;
                if (CHECK(x,row) || CHECK(x, col[j]) || CHECK(x, matrix[m_idx]))
                    return false;
                else {
                    SET(x, row);
                    SET(x, col[j]);
                    SET(x, matrix[m_idx]);
                }
            }
        }
        return true;
    }
};

Other tips:

I understand the meaning of divisible:

The i = 0, 1, 2 maps to 0; 3, 4, 5 maps to 1; such a thing we can by (i / 3) * 3 is achieved.

Published 137 original articles · won praise 19 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43338695/article/details/102750656