6.1 KiB
6.1 KiB
Leetcode Valid-Sodoku
2022-06-13 12:56
Data structures:
#DS #vector
Difficulty:
#leetcode #coding_problem #difficulty_easy
Related topics:
Links:
Problem
Determine if a 9 x 9
Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
- Each row must contain the digits
1-9
without repetition. - Each column must contain the digits
1-9
without repetition. - Each of the nine
3 x 3
sub-boxes of the grid must contain the digits1-9
without repetition.
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.
Examples
**Input:** board =
[["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
**Input:** board =
[["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.
Constraints
- board.length == 9
- board[i].length == 9
- board[i][j] is a digit
1-9
or'.'
.
Thoughts
This should be a follow-up of Leetcode Reshape-The-Matrix, I tried to implement using unordered set, but regular arrays should suffice.
Besides overthinking, I also spent a lot of time learning how to use sets and init multi-dimensional vectors.
Take TWO: Use a hash table to store whether an element is present:
int usedRow[9][10] = {};
int usedCol[9][10] = {};
int usedGrid[9][10] = {};
Solution
My new solution using hash map
class Solution {
public:
bool isValidSudoku(vector<vector<char>> &board) {
// from 0 to 9
int usedRow[9][10] = {};
int usedCol[9][10] = {};
int usedGrid[9][10] = {};
int grid;
int boardVal;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
grid = i / 3 * 3 + j / 3;
boardVal = board[i][j];
if (boardVal == '.') {
continue;
}
boardVal = boardVal - '0';
if (usedRow[i][boardVal] || usedCol[j][boardVal] ||
usedGrid[grid][boardVal]) {
return false;
}
usedRow[i][boardVal]++;
usedCol[j][boardVal]++;
usedGrid[grid][boardVal]++;
}
}
return true;
}
};
Bad solution :(
class Solution {
public:
bool isValidSudoku(vector<vector<char>> &board) {
// store info as unordered_set
// even(it % 2 == 0):
// horizontal
// odd(it % 2 == 1):
// vertical
vector<vector<vector<unordered_set<int>>>> sets(9);
for (int i = 0; i < 9; i++) {
sets[i] = vector<vector<unordered_set<int>>>(2);
for (int j = 0; j < 2; j++) {
sets[i][j] = vector<unordered_set<int>>(3);
}
}
for (int i = 0; i < 9; i++) {
// populate set[i][0], horizontal
for (int j = 3 * (i / 3); j < 3 * (i / 3) + 3; j++) { // iterate rows
for (int k = 3 * (i % 3); k < 3 * (i % 3) + 3;
k++) { // iterate over cols
if (board[j][k] >= '0' && board[j][k] <= '9') {
// Insert that if it is a number
auto valPair = sets[i][0][j % 3].insert(board[j][k] - '0');
// there is a duplicate
if (valPair.second == false) {
return false;
}
}
}
}
// if the whole set is empty
bool is_empty = true;
for (int j = 0; j < 3; j++) {
if (!sets[i][0][j].empty()) {
is_empty = false;
continue;
}
}
if (is_empty == true) {
continue;
}
// check sets[i][0][*] is legit, and move data to set[i][0][0]
unordered_set<int> tmp;
for (auto tmpsets : sets[i][0]) {
for (int j : tmpsets) {
auto result = tmp.insert(j);
if (result.second == false) {
return false;
}
}
}
// populate set[i][0], vertically
for (int k = 3 * (i % 3); k < 3 * (i % 3) + 3; k++) { // iterate over cols
for (int j = 3 * (i / 3); j < 3 * (i / 3) + 3; j++) { // iterate rows
if (board[j][k] >= '0' && board[j][k] <= '9') {
// Insert that if it is a number
auto valPair = sets[i][1][k % 3].insert(board[j][k] - '0');
// there is a duplicate
if (valPair.second == false) {
return false;
}
}
}
}
}
// check each row and col.
for (int i = 0; i < 9; i++) {
for (int k = 0; k < 3; k++) {
// check for rows
if (i % 3 != 2) {
sets[i + 1][0][k].merge(sets[i][0][k]);
if (!sets[i][0][k].empty()) {
printf("Found at %d\n", i);
for (int val : sets[i][0][k]) {
printf("%d ", val);
}
printf("\n");
return false;
}
}
// check for cols
if (i < 6) {
sets[i + 3][1][k].merge(sets[i][1][k]);
if (!sets[i][1][k].empty()) {
printf("Found duplicated col at %d, %d\n", i, k);
for (int val : sets[i][1][k]) {
printf("%d ", val);
}
printf("\n");
return false;
}
}
}
}
return true;
}
};