Leetcode 37 Sudoku Solver
题意
解决一个数独问题,有一个9*9 的矩阵,其中是字符
和'.'
满足每一行每一列,以及每一个3 x 3
的小块满足只有从1到9的字符,一定且仅有唯一的答案
题目链接
https://leetcode.com/problems/sudoku-solver/description/
思考
对于数独来说,对于每一个'.'
格子而言,我都可以从1填到9,一共有81个格子,可以想像一颗有81层,每一个分支从1选到9的值。二维矩阵可以转化成一维来处理。
为什么这一题dfs要返回值?
因为如果是个void function,不返回true活着false,上一层函数就不知道信息。
我们举个例子
比如我需要从S走到E,如果不返回值,当找到一条正确路径的时候,上一层的dfs会擦除路径。void dfs
会适合那种打印路径的问题。
S . .
X . .
. . E
思路
用dfs遍历所有非'.'
的格子,从1填到9,当填完所有的81个格子时停下并且返回当前填空的状态。
class Solution {
public:
int m = 0;
int n = 0;
void solveSudoku(vector<vector<char>>& g) {
m = g.size();
n = g[0].size();
dfs(0, g);
}
bool dfs(int u, vector<vector<char>>& g) {
if ( u == m * n) {
return true;
}
int x = u / m;
int y = u % m;
if(g[x][y] != '.') {
return dfs(u+1, g);
} else {
for(int i = 1; i <= 9; i++) {
g[x][y] = i + '0';
if(check(x,y, g) && dfs(u+1, g)) {
return true;
}
g[x][y] = '.';
}
}
return false;
}
bool check(int x, int y, vector<vector<char>>& g) {
char c = g[x][y];
for(int i = 0; i < 9; i++) {
if(i != x && g[i][y] == c) return false;
if(i != y && g[x][i] == c) return false;
int row = x/3*3 + i/3;
int col = y/3*3 + i%3;
if(x!= row && y != col && g[row][col] == c) return false;
}
return true;
}
};
时间复杂度:
O
(
9
81
)
=
O
(
1
)
O(9^{81}) = O(1)
O(981)=O(1)
空间复杂度:
O
(
1
)
O(1)
O(1)