Keshawn_lu's Blog

Leetcode 37. 解数独

字数统计: 513阅读时长: 2 min
2020/09/15 Share

题目简介:

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

​ 一个数独。

​ 答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.'
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

思路:

深搜+回溯,主要还是判断的问题。

对于在某个位置放下一个数字,我们需要判断这一行这一列有没有相同的数字,还需要判断3x3的网格中有没有相同的数字。

当某个位置可以成功被放下时,进行下一步的深搜,若9个数字都不能在该位置放下,说明这种解法是错的,return false

tip:

  • 需要注意3x3网格的位置开始坐标的计算。

代码如下:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {
public:

bool dfs(vector<vector<char>>& board){

for(int i = 0; i < board.size(); i++){

for(int j = 0; j < board[i].size(); j++){

if(board[i][j] != '.')
continue;

for(char k = '1'; k <= '9'; k++){

if(judge(board, i, j, k)){

board[i][j] = k;
if(dfs(board))
return true;
board[i][j] = '.'; //回溯
}
}

return false; // 9个数字都不能成功放下
}
}

return true; //找到解了
}


bool judge(vector<vector<char>>& board, int i, int j, char k){

//判断行
for(int row = 0; row < 9; row++){

if(board[row][j] == k)
return false;
}

//判断列
for(int col = 0; col < 9; col++){

if(board[i][col] == k)
return false;
}

//判断3x3
int start_x = j / 3 * 3; //关键, 位置不能弄错
int start_y = i / 3 * 3;

for(int row = start_y; row < start_y + 3; row++){

for(int col = start_x; col < start_x + 3; col++){

if(board[row][col] == k)
return false;
}
}

return true;
}

void solveSudoku(vector<vector<char>>& board) {

dfs(board);
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: