当前位置:网站首页>经典递归回溯问题之——解数独(LeetCode 37)
经典递归回溯问题之——解数独(LeetCode 37)
2022-08-04 07:28:00 【dor.yang】
题目内容
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
示例 1:
输入:board = [[“5”,“3”,“.”,“.”,“7”,“.”,“.”,“.”,“.”],[“6”,“.”,“.”,“1”,“9”,“5”,“.”,“.”,“.”],[“.”,“9”,“8”,“.”,“.”,“.”,“.”,“6”,“.”],[“8”,“.”,“.”,“.”,“6”,“.”,“.”,“.”,“3”],[“4”,“.”,“.”,“8”,“.”,“3”,“.”,“.”,“1”],[“7”,“.”,“.”,“.”,“2”,“.”,“.”,“.”,“6”],[“.”,“6”,“.”,“.”,“.”,“.”,“2”,“8”,“.”],[“.”,“.”,“.”,“4”,“1”,“9”,“.”,“.”,“5”],[“.”,“.”,“.”,“.”,“8”,“.”,“.”,“7”,“9”]]
输出:[[“5”,“3”,“4”,“6”,“7”,“8”,“9”,“1”,“2”],[“6”,“7”,“2”,“1”,“9”,“5”,“3”,“4”,“8”],[“1”,“9”,“8”,“3”,“4”,“2”,“5”,“6”,“7”],[“8”,“5”,“9”,“7”,“6”,“1”,“4”,“2”,“3”],[“4”,“2”,“6”,“8”,“5”,“3”,“7”,“9”,“1”],[“7”,“1”,“3”,“9”,“2”,“4”,“8”,“5”,“6”],[“9”,“6”,“1”,“5”,“3”,“7”,“2”,“8”,“4”],[“2”,“8”,“7”,“4”,“1”,“9”,“6”,“3”,“5”],[“3”,“4”,“5”,“2”,“8”,“6”,“1”,“7”,“9”]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:
提示:
board.length == 9
board[i].length == 9
board[i][j] 是一位数字或者 ‘.’
题目数据 保证 输入数独仅有一个解
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
这道题其实往简单了想,和八皇后问题可以说是一个思路。就是一个个的尝试,在循环中使用递归函数。只要后续回来了,就说明我们目前这个思路有问题,需要我们回过头来,重新尝试目前这个点位的选择,如果这个点位没有可以选择的了,就说明之前的选择就已经错了,我们直接回去重新尝试即可。
这个代码的整体思路其实说不上多复杂,但是我在写的时候虽然看着是一次过,但是其实改了好久,就是因为代码的结果始终存在各种的问题,在没有意识到问题出现在哪里的时候,那些各种错误千奇百怪的,不过后来我意识到了错误的点之后很快就解决了。发现的契机就是我意识到,一些已经给定了的数也被改动了,而这在我们的代码中显然是不应该的。
随后,我就反应过来,出现问题的点在于虽然给定数据的点位在当时第一次到的时候,我们设置好了叫他直接返回,但是在后面有问题了,返回到这个点之后,他会直接走到我们的循环里面,然后获得一个新的数据。这显然就错了。
所以,我是用的另一个数组来记录和判定,不过也可以直接后面return,应该也是可以的。
代码
class Solution {
public:
int heng[9][10]={
0};
int shu[9][10]={
0};
int kuai[9][10]={
0};
int valid=0;
int tu[9][9]={
0};
void dfs(vector<vector<char>>& board,int x,int y)
{
if(x==9){
valid=1;
// for(int i=0;i<9;i++){
// for(int j=0;j<9;j++){
// cout<<board[i][j]<<" ";
// }
// cout<<endl;
// }
return;
}
if(tu[x][y]==0){
// cout<<x<<" "<<y<<endl;
if(y==8){
dfs(board,x+1,0);
}
else{
dfs(board,x,y+1);
}
}
int hao=x/3*3+y/3;
if(tu[x][y]==1){
for(int i=1;i<10&&valid==0;i++){
if(heng[x][i]==0&&shu[y][i]==0&&kuai[hao][i]==0){
board[x][y]='0'+i;
// cout<<x<<" "<<y<<" "<<board[x][y]<<endl;
heng[x][i]=1;
shu[y][i]=1;
kuai[hao][i]=1;
if(y==8){
dfs(board,x+1,0);
}
else{
dfs(board,x,y+1);
}
heng[x][i]=0;
shu[y][i]=0;
kuai[hao][i]=0;
}
}
}
// cout<<"chonglai"<<endl;
return;
}
void solveSudoku(vector<vector<char>>& board) {
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.'){
tu[i][j]=1;
continue;
}
int num=board[i][j]-'0';
heng[i][num]=1;
shu[j][num]=1;
int hao=i/3*3+j/3;
kuai[hao][num]=1;
}
}
dfs(board,0,0);
}
};
边栏推荐
猜你喜欢
likeshop外卖点餐系统开源啦100%开源无加密
DropBlock: Regularization method and reproduction code for convolutional layers
设计信息录入界面,完成人员基本信息的录入工作,
redis stream 实现消息队列
2022的七夕,奉上7个精美的表白代码,同时教大家改源码快速自用
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
分布式计算实验1 负载均衡
likeshop外卖点餐系统【100%开源无加密】
[想要访问若依后台]若依框架报错401请求访问:error认证失败,无法访问系统资源
leetcode 22.7.31(1)两数之和 (2)整数除法
随机推荐
中职网络安全竞赛B模块新题
unity webgl报 Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON
【学习笔记】AGC036
LLVM编译技术应用分析
【并发】概念
金仓数据库KingbaseES客户端编程接口指南-JDBC(5. JDBC 查询结果集处理)
登录拦截实现过程
小程序如何使用订阅消息(PHP代码+小程序js代码)
redis stream 实现消息队列
unity 循环选择器
TCP协议详解
GIS数据与CAD数据间带属性字段互相转换还原工具,解决ArcGIS等软件进行GIS数据转CAD数据无法保留属性字段问题
unity2D横版游戏教程7-敌人AI死亡效果
【selenium自动化】第四篇,结合testNg
The school to apply for link
字节跳动岗位薪酬体系曝光,看完我真的酸了...
LeetCode 97. 交错字符串
8.2学习记录
千万级别的表分页查询非常慢,怎么办?
FCN - the originator of semantic segmentation (based on tf-Kersa reproduction code)