LeetCode/solutions/36. Valid Sudoku.md
2019-01-05 17:27:29 +08:00

136 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [36. Valid Sudoku](https://leetcode.com/problems/valid-sudoku/)
# 思路
题意就是要求判断给定的board是否是一个合法的数独。
## 思路一
开辟一个大小为9的数组mp(实际代码中为了直接用1-9的下标所以开的大小为10的数组下同)遍历三次数独分别判断row、column、sub_box是否合法就完事。
## 思路二
思路一在每次循环后都要讲数组mp清零也可以考虑用空间换时间的思路多开几个一次性的数组这样就不用清零了。
注意第i行第j列(0 <= i,j <=2)的sub_box是第`i*3 + j`个sub_box。
## 思路三
前面两种思路都需要对board遍历三次所以代码写得很冗长一点都不elegant其实一次遍历就够了。
需要注意的是第i行第j列(0 <= i,j <= 8)的元素所在的sub_box是第`3 * (i/3) + j/3`个,注意`i/3`需要加括号。(这里的i/3和j/3就是对应的思路二中的i,j)
# C++
## 思路一
``` C++
class Solution {
private:
bool sub_box_is_valid(int x, int y, const vector<vector<char>>& board, vector<int>&mp){
// x和y是这个sub_box左上角的坐标
for(int k = 1; k <= 9; k++) mp[k] = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(board[i+x][j+y] == '.') continue;
if(mp[board[i+x][j+y] - '0'] > 0) return false;
mp[board[i+x][j+y] - '0']++;
}
}
return true;
}
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector<int>mp(10, 0);
// 判断行
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] == '.') continue;
if(mp[board[i][j] - '0'] > 0) return false;
mp[board[i][j] - '0']++;
}
for(int k = 1; k <= 9; k++) mp[k] = 0; // 清零数组
}
// 判断列
for(int j = 0; j < 9; j++){
for(int i = 0; i < 9; i++){
if(board[i][j] == '.') continue;
if(mp[board[i][j] - '0'] > 0) return false;
mp[board[i][j] - '0']++;
}
for(int k = 1; k <= 9; k++) mp[k] = 0;
}
// 判断sub_box
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(sub_box_is_valid(i*3, j*3, board, mp)) continue;
return false;
}
}
return true;
}
};
```
## 思路二
``` C++
class Solution {
private:
bool sub_box_is_valid(int x, int y, const vector<vector<char>>& board, vector<int>&mp){
//for(int k = 1; k <= 9; k++) mp[k] = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(board[i+x][j+y] == '.') continue;
if(mp[board[i+x][j+y] - '0'] > 0) return false;
mp[board[i+x][j+y] - '0']++;
}
}
return true;
}
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector<vector<int>>mp1(10, vector<int>(10, 0));
vector<vector<int>>mp2(10, vector<int>(10, 0));
vector<vector<int>>mp3(10, vector<int>(10, 0));
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] == '.') continue;
if(mp1[i][board[i][j] - '0'] > 0) return false;
mp1[i][board[i][j] - '0']++;
}
}
for(int j = 0; j < 9; j++){
for(int i = 0; i < 9; i++){
if(board[i][j] == '.') continue;
if(mp2[j][board[i][j] - '0'] > 0) return false;
mp2[j][board[i][j] - '0']++;
}
}
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
// 第i行第j列(0 <= i,j <=2)的sub_box是第i*3 + j个sub_box。
if(sub_box_is_valid(i*3, j*3, board, mp3[i*3 + j])) continue;
return false;
}
}
return true;
}
};
```
## 思路三
``` C++
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
// vector<vector<int>>mp1(10, vector<int>(10, 0));
int mp1[10][10] = {0}, mp2[10][10] = {0}, mp3[10][10] = {0};
int n, sub_box_index;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] == '.') continue;
n = board[i][j] - '0';
sub_box_index = 3 * (i/3) + j/3; // 注意i/3需要加括号
if(mp1[i][n] || mp2[j][n] || mp3[sub_box_index][n]) return false;
mp1[i][n] = mp2[j][n] = mp3[sub_box_index][n] = 1;
}
}
return true;
}
};
```