力扣Java解数独_【Daily Interview】- 21 解数独

题目

6fac909f1ef290447034c03fd94f4517.png

分析

对数独规则不太清楚的读者可以看看这里:数独。

同之前的单词搜索和 N 皇后问题类似,数独的解题思路同样简单粗暴:看看当前位置能不能填

如果可以则填入,继续判断下一个位置

如果遇到死路则退回来填入其他结果

而这也就是回溯算法的核心了,以数独为例,我们可以看看下面的流程图,方便理解回溯算法:

b1fb04a7939836151b07704967db2d73.png

那么我们可以根据这个套路,完成代码的宏观架构:var solveSudoku = function (board) {  // 遍历棋盘

for (let i = 0; i 

solveSudoku(board);

board[i][j] = ".";

}

}

}

}

};复制代码

对于上述代码,不能忘的是考虑边界条件:何时回退显然当当前格子所有值都不能填入的时候,就应该回退了,那么应该在遍历完 1~9 的可选值之后返回 false

何时结束整个棋盘都被填完的时候,这时说明解出答案,就可以结束了,这个时候应该返回 true

代码如下:var solveSudoku = function (board) {  // 遍历棋盘

for (let i = 0; i 

+          if (solveSudoku(board)) return true;

board[i][j] = ".";

}

}

+      return false;

}

}

+  return true;

};复制代码

接下来就是细节上的实现:如何判断当前格子是否能填入对应数字。

对于这个问题,我们理清规则其实不难:当前行已经有的所有值都不能与 value 相等

当前列已经有的所有值都不能与 value 相等

当前 3 x 3 的九宫格内所已经有的所有值都不能与 value 相等

前二者比较简单,只需固定死 row 和 col 即可,而第三个,我们则需要首先找到当前遍历到的格子属于哪一块九宫格。

这里我们来看一个数独:

96d312ba0f34766fc6e68197e319b6d8.png

可以看到,9 个九宫格将整个 9 x 9 的棋盘分成了 9 块,那么我们完全可以忽略掉小格子,将其转化成 3 x 3 的棋盘。const x = Math.floor(row / 3) * 3;const y = Math.floor(col / 3) * 3;复制代码

这样就可以定位是具体的九宫格了。

综上,完善 canSet 代码:const canSet = (board, row, col, value) => {  const x = Math.floor(row / 3) * 3;  const y = Math.floor(col / 3) * 3;

// 九宫格内有数字与 value 相等

for (let i = 0; i 

}

}

}// 行列有数字与 value 相等

for (let i = 0; i 

}

}  return true;

};复制代码

结果如下:

55e641c55a7f11770c36d60c7a0634ae.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值