LeetCode 37 Sudoku Solver
来源:互联网 发布:淘宝囤货节在哪 编辑:程序博客网 时间:2024/05/21 01:55
题意:
给出一个一定有解的填了一部分的数独,要求填满它。
思路:
我是分2步解决这个问题的:
第1步检查每个格子可能填哪几个数字,第2步dfs搜索结果。
dfs的时候只搜索第1步中找出的可能的数字,每次尝试填入一个格子并更新当前行、当前列、当前3*3格子的可选数字,注意回溯。
我的代码3ms就可以跑完,效率还是很不错的。
代码:
class Solution {public: void solveSudoku(vector<vector<char>> &board) { can.clear(); int besti = 0, bestj = 0, bestcnt = 10; for (int i = 0; i < n; ++i) { vector<set<int>> tmp; for (int j = 0; j < n; ++j) { if (board[i][j] != '.') { tmp.push_back(set<int> {}); continue; } set<int> now = candidate(i, j, board); int cnt = now.size(); // if(cnt == 1){ // board[i][j] = *(now.begin()) + '1'; // tmp.push_back(set<int>{}); // continue; // } tmp.push_back(now); if (cnt < bestcnt) { besti = i; bestj = j; bestcnt = cnt; } } can.push_back(tmp); } if (bestcnt != 10) { if (dfs(besti, bestj, board)) { printf("success!"); } else { printf("fuck!"); } } }private: int n = 9; vector<vector<set<int>>> can; set<int> candidate(int i, int j, vector<vector<char>> &board) { bool app[9]; memset(app, false, sizeof(app)); for (int k = 0; k < n; ++k) { if (board[i][k] != '.') { app[board[i][k] - '1'] = true; } if (board[k][j] != '.') { app[board[k][j] - '1'] = true; } int di = i / 3 * 3 + k / 3, dj = j / 3 * 3 + k % 3; if (board[di][dj] != '.') { app[board[di][dj] - '1'] = true; } } set<int> res; for (int k = 0; k < n; ++k) { if (!app[k]) { res.insert(k); } } return res; } bool dfs(int x, int y, vector<vector<char>> &board) { stack<pair<int, int>> effect; set<int> now = can[x][y]; can[x][y].clear(); for (int k : now) { // printf("%d %d %d\n", x + 1, y + 1, k + 1); board[x][y] = k + '1'; for (int i = 0; i < n; ++i) { if (i != y && can[x][i].find(k) != can[x][i].end()) { can[x][i].erase(k); effect.push(make_pair(x, i)); } if (i != x && can[i][y].find(k) != can[i][y].end()) { can[i][y].erase(k); effect.push(make_pair(i, y)); } int di = x / 3 * 3 + i / 3, dj = y / 3 * 3 + i % 3; if (can[di][dj].find(k) != can[di][dj].end()) { can[di][dj].erase(k); effect.push(make_pair(di, dj)); } } int besti = 0, bestj = 0, bestcnt = 10; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] == '.' && can[i][j].size() < bestcnt) { besti = i; bestj = j; bestcnt = can[i][j].size(); } } } if (bestcnt != 0) { if (bestcnt == 10 || dfs(besti, bestj, board)) { return true; } } while (!effect.empty()) { pair<int, int> e = effect.top(); effect.pop(); can[e.first][e.second].insert(k); } } board[x][y] = '.'; can[x][y] = now; return false; }};
阅读全文
0 0
- Leetcode 37 Sudoku Solver
- Leetcode 37: Sudoku solver
- [leetcode 37] Sudoku Solver
- LeetCode(37) Sudoku Solver
- leetcode 37:Sudoku Solver
- leetcode 37: Sudoku Solver
- Leetcode #37 Sudoku Solver
- leetcode-37 Sudoku Solver
- leetcode 37:Sudoku Solver
- LeetCode 37: Sudoku Solver
- LeetCode 37 - Sudoku Solver
- LeetCode(37)-Sudoku Solver
- leetcode 37 Sudoku Solver
- LeetCode 37 Sudoku Solver
- LeetCode 37 SudoKu Solver
- LeetCode 37 Sudoku Solver
- leetcode-37-sudoku solver
- Leetcode (37) Sudoku Solver
- 视频终端测试,音视频性能检测
- css块级内联元素
- Linux用户分类_DNS
- mysql介绍——基础加强
- python GIL
- LeetCode 37 Sudoku Solver
- 欢迎使用CSDN-markdown编辑器
- 几维安全论:平板电脑与智能手机安全性
- 1年经验与10年经验一样的代码!程序员该如何回归简单?
- Qt学习笔记-文件操作
- Redis cluster配置文件和集群状态详解
- MQ消息中间件技术浅析
- 将jar文件安装为系统服务
- [电脑问题]WIN7 64位启动 printui.dll出现问题。