持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
前言
给大家分享一个解数独的小算法,数独是每一行每一列,不能出现重复的值,并且每个3*3的格子内的数字也只能出现一次,问题是现在格子内有很多数字存在,现在把不合格的数字给赋值为空
递归+回溯
- 遍历
首先需要挨个进行遍历最外层
9*9的方格和格子内层数,这样就可以遍历到每一个小方块
for(var i = 0;i<9;i++){
for(var l = 0;l<9;i++){}
}
- 如果为空
遍历如果每个小方格不能与小数点
.(空格用这个表示),那么把该循环结束,继续下次循环
if(tables[y][l]!='.'){continue}
说明:比如说遍历到某一个格子,在内有数字,不能再放数字了,则跳出循环
- 如果不为空 如果是小数点(空格),则需要两个判定条件:
- 判定这个空格子,放数字是否符合数独条件,如果判定允许则把该数字赋值上去,并进行回溯
for(var k = 1;k<=9;k++){
if(isNum(y,l,k).toString()){
shudu[y][l] = k.toString()
if(sudoKu(shudu)){return true}
shudu[y][l] = '.'
}
}
如果遍历的该数字可以放到方格内,那么就赋值到方格内,随后进行递归,递归结束后,再次进行遍历,如果该数字不能放到方格内,则进行回溯给方格赋值为空格
判定数组能不能放
function isNum(r,c,k){
for(let o =0;o<9;o++){
if(shudu[r][o] === k || shudu[o][c] == k){
return false
}
}
}
如果没有数字,那么可以在内放1-9内的其中一个数字,循环判定放那个数字合适,如果方格的某行某列的一个数字等于遍历的数字,则相同要继续遍历
- 判断
3*3小方格的索引值,在那个方格内 首先获取小方格的位置(x轴和y轴),循环遍历小方格,如果每个小方格内的数据等与0-9之一,那么则当前数字不符合要求
const X = math.floor(r*3)*3
const Y = math.floor(r*3)*3
for(let p =0;p<3;p++){
for(let j =0;j<3;j++){
if(shudu[X+i][p+j] == k){
return false
}
}
}
思路:通过回溯和递归形式,判定条件改成了每一行每一列的值和3*3的每一行每列的值