LeetCode--36. Valid Sudoku

I. Description of the problem

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.

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.

Second, problem-solving ideas

At first glance I thought it was only the stops, will be very complicated. After reading the title, I found only asked to judge the numbers on the current board is not valid, no need to consider this final number is not the only possible solution. So this is equivalent to only need to determine whether the current existing board meets the requirements sudoku rules.

Sudoku rules require that each row, each column, and each of 3x3the sub-board, whether to include 1-9the nine figures is not repeated. Now consider, certainly need to scan the entire board again, then we can set up an array of three states, as well as scanned next to each record 行/列/子棋盘number has appeared, if the scan to a certain 行/列/子棋盘there in front of repeated elements have appeared directly return false; until when the end of the scan, but also to find duplicate elements described effective board, returns true. However, due to record every 行/列/子棋盘state, we need to declare three large arrays, so the higher the consumption of space, there should be a more optimal solution.

General idea of ​​solving the comments area are similar, the main difference between then seek how to store the state array. One method is optimized using bit operations are implemented, this method only saves the state of a short line to save a lot of space, efficiency is also improved.

  1. The status of each line is initialized to 0;
  2. Encountered a number num, num bit will be left with a number of states with the operation, if the result is not 0, indicating a repeat, return false; otherwise, no repetition, update state, i.e., the number of two or perform operations.

参考:
C++ very simple and easy understand. using bit operation
My C++ code (O(n2) time and space)

Third, the code

Solution 1

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
      
      
class {
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector< vector< bool>> rows( 9, vector< bool>( 9, false));
vector< vector< bool>> columns( 9, vector< bool>( 9, false));
vector< vector< bool>> sub_box( 9, vector< bool>( 9, false));
for( int i = 0; i < 9; i++)
{
for( int j = 0; j < 9; j++)
{
if(board[i][j] == '.') continue;
int sub_box_index = (i/ 3)* 3 + (j/ 3);
int num = board[i][j] - '1';
if(rows[i][num] || columns[j][num] || sub_box[sub_box_index][num])
return false;
rows[i][num] = columns[j][num] = sub_box[sub_box_index][num] = true;
}
}
return true;
}
};

利用位操作

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
      
      
class {
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector< short> col( 9, 0);
vector< short> block( 9, 0);
vector< short> row( 9, 0);
for ( int i = 0; i < 9; i++)
for ( int j = 0; j < 9; j++)
{
if (board[i][j] != '.')
{
int idx = 1 << (board[i][j] - '0');
if (row[i] & idx || col[j] & idx || block[i/ 3 * 3 + j / 3] & idx)
return false;
row[i] |= idx;
col[j] |= idx;
block[i/ 3 * 3 + j/ 3] |= idx;
}
}
return true;
}
};

解法3

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
      
      
class {
public:
bool isValidSudoku(vector<vector<char> > &board) {
char existNum[ 10][ 10]={ 0};
int i,j;
for(i= 0; i< 9; i++)
{
for(j= 0; j< 9; j++)
{
if(board[i][j]!= '.')
{
if(existNum[i][board[i][j] - '0'] & 0x1) return false;
if(existNum[j][board[i][j] - '0'] & 0x2) return false; // check if the j-col already has such number, 2-LSB
if(existNum[(i/ 3) * 3 + j/ 3][board[i][j] - '0'] & 0x4) return false; // check if the k-subblock already has such number, 3-LSB
existNum[i][board[i][j] - '0'] ^= 0x1;
existNum[j][board[i][j] - '0'] ^= 0x2;
existNum[(i/ 3) * 3 + j/ 3][board[i][j] - '0'] ^= 0x4;
}
}
}
return true;
}
};

Original: Big Box  LeetCode - 36 Valid Sudoku.


Guess you like

Origin www.cnblogs.com/wangziqiang123/p/11618371.html