Leetcode | Valid Sudoku & Sudoku Solver

本文介绍了一种通过暴力遍历验证数独合法性的方法,并提供了一个使用回溯算法解决数独问题的实现方案。文章详细展示了如何利用一维和二维数组记录已存在的数字,以避免重复数字出现,确保数独的正确性和唯一解的存在。

判断valid,没有更好的方法,只能brute force。

 1 class Solution {
 2 public:
 3     bool isValidSudoku(vector<vector<char> > &board) {
 4         
 5         int n;
 6         for (int i = 0; i < 9; ++i) {
 7             vector<bool> contained(9, false);
 8             for (int j = 0; j < 9; ++j) {
 9                 if (board[i][j] == '.') continue;
10                 n = board[i][j] - '0' - 1;
11                 if (contained[n]) return false;
12                 contained[n] = true;
13             }
14         }
15         
16         for (int i = 0; i < 9; ++i) {
17             vector<bool> contained(9, false);
18             for (int j = 0; j < 9; ++j) {
19                 if (board[j][i] == '.') continue;
20                 n = board[j][i] - '0' - 1;
21                 if (contained[n]) return false;
22                 contained[n] = true;
23             }
24         }
25         
26         for (int i = 0; i < 3; ++i) {
27             for (int j = 0; j < 3; ++j) {
28                 vector<bool> contained(9, false);
29                 for (int k = 0; k < 3; ++k) {
30                     for (int m = 0; m < 3; ++m) {
31                         if (board[i*3+k][j*3+m] == '.') continue;
32                         n = board[i*3+k][j*3+m] - '0' - 1;
33                         if (contained[n]) return false;
34                         contained[n] = true;
35                     }
36                 }
37             }
38         }
39         return true;
40     }
41 };

求解决方案也只有backtrack。

 1 class Solution {
 2 public:
 3     void solveSudoku(vector<vector<char> > &board) {
 4         list<int> unsolved;
 5         getUnsolved(board, unsolved);
 6         recursive(board, unsolved);
 7     }
 8     
 9     bool recursive(vector<vector<char> > &board, list<int> &unsolved) {
10         if (unsolved.empty()) return true;
11         int loc = unsolved.front();
12         int row = loc / 9;
13         int col = loc % 9;
14         
15         vector<bool> contained(9, false);
16         int n;
17         for (int i = 0; i < 9; ++i) {
18             if (board[row][i] != '.') {
19                 contained[board[row][i] - '0' - 1] = true;
20             }
21             if (board[i][col] != '.') {
22                 contained[board[i][col] - '0' - 1] = true;
23             }
24         }
25         
26         row = row / 3; col = col / 3;
27         for (int i = 0; i < 3; ++i) {
28             for (int j = 0; j < 3; ++j) {
29                 if (board[row * 3 + i][col * 3 + j] != '.') {
30                     contained[board[row * 3 + i][col * 3 + j] - '0' - 1] = true;
31                 }
32             }
33         }
34         
35         row = loc / 9; col = loc % 9;
36         for (int i = 0; i < 9; ++i) {
37             if (!contained[i]) {
38                 board[row][col] = i + 1 + '0'; 
39                 unsolved.pop_front();
40                 if (recursive(board, unsolved)) return true;
41                 board[row][col] = '.';
42                 unsolved.push_front(loc);
43             }
44         }
45         
46         return false;
47     }
48     
49     void getUnsolved(vector<vector<char> > &board, list<int> &unsolved) {
50         for (int i = 0; i < 9; i++) {
51             for (int j = 0; j < 9; ++j) {
52                 if (board[i][j] == '.') {
53                     unsolved.push_back(i * 9 + j);
54                 }
55             }
56         }
57     }
58 };

用unsolved数组可以避免每次都需要从头扫到尾去找下一个元素。

用contained数组先保存了在该行该格该九宫格里已经存在的数字。这样就可以直接去试验剩下的数字,而不需要每次都再检查一遍插入的值是否合法。

backtrack是一个要有返回值,否则都不知道你backtrack到头了没,是否找到解决方案了。

 

转载于:https://www.cnblogs.com/linyx/p/3702450.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值