main.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * @lc app=leetcode.cn id=37 lang=cpp
  3. *
  4. * [37] 解数独
  5. */
  6. #include <bits/stdc++.h>
  7. using namespace std;
  8. // @lc code=start
  9. void print(const vector<vector<char>>& board) {
  10. for (int i = 0; i < 9; ++i) {
  11. for (int j = 0; j < 9; ++j) {
  12. cout << board[i][j] << ",";
  13. }
  14. cout << endl;
  15. }
  16. }
  17. class Solution {
  18. public:
  19. void solveSudoku(vector<vector<char>>& board) {
  20. // 需要求解的位置坐标,最长81
  21. vector<pair<int, int>> empty;
  22. for (int i = 0; i < 9; ++i) {
  23. for (int j = 0; j < 9; ++j) {
  24. if (board[i][j] == '.') {
  25. empty.emplace_back(i, j);
  26. }
  27. }
  28. }
  29. int n = empty.size();
  30. // 检查一个位置合法性,无递归,空间O(m),m==9
  31. function<bool(int, int)> vaild = [&](int i, int j) -> bool {
  32. array<int, 9> exist1 = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  33. array<int, 9> exist2 = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  34. array<int, 9> exist3 = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  35. for (int k = 0; k < 9; ++k) {
  36. if (board[i][k] != '.') {
  37. if (exist1[board[i][k] - '1']) {
  38. return false;
  39. }
  40. exist1[board[i][k] - '1'] = 1;
  41. }
  42. if (board[k][j] != '.') {
  43. if (exist2[board[k][j] - '1']) {
  44. return false;
  45. }
  46. exist2[board[k][j] - '1'] = 1;
  47. }
  48. }
  49. int r = i / 3 * 3;
  50. int c = j / 3 * 3;
  51. for (int k = 0; k < 3; ++k) {
  52. for (int l = 0; l < 3; ++l) {
  53. if (board[r + k][c + l] != '.') {
  54. if (exist3[board[r + k][c + l] - '1']) {
  55. return false;
  56. }
  57. exist3[board[r + k][c + l] - '1'] = 1;
  58. }
  59. }
  60. }
  61. return true;
  62. };
  63. // 递归回溯求解,内存O(1),调用深度最多n(n<=81)
  64. function<void(int)> f = [&](int i) {
  65. if (i == n) {
  66. throw exception();
  67. }
  68. for (int j = 0; j < 9; ++j) {
  69. board[empty[i].first][empty[i].second] = j + '1';
  70. if (vaild(empty[i].first, empty[i].second)) {
  71. f(i + 1);
  72. }
  73. board[empty[i].first][empty[i].second] = '.';
  74. }
  75. };
  76. try {
  77. f(0);
  78. } catch (const exception& e) {
  79. }
  80. // cant be solved
  81. }
  82. };
  83. // @lc code=end
  84. int main() {
  85. Solution s;
  86. vector<vector<char>> b = {{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
  87. {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
  88. {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
  89. {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
  90. {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
  91. {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
  92. {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
  93. {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
  94. {'.', '.', '.', '.', '8', '.', '.', '7', '9'}};
  95. s.solveSudoku(b);
  96. print(b);
  97. }