回溯算法之解数独

 

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。

一个数独。

答案被标成红色。

Note:

给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

 

/*
 * @lc app=leetcode.cn id=37 lang=javascript
 *
 * [37] 解数独
 */

// @lc code=start
/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var solveSudoku = function(board) {
    let l = []  
    let r = []
    let k = []
    //初始化数据结构
    for(let i=0;i<board.length;i++){
        for(let j=0;j<board[i].length;j++){
            let num = board[i][j]
            let h = Math.floor((i)/3); 
            let m = Math.floor((j)/3); 
            let k_index = m+(h*3)
            if(num!='.'){
                !l[i] ? l[i] = {}:null;
                !r[j] ? r[j] = {}:null;
                !k[k_index] ? k[k_index]  = {}:null;

                l[i][num] =  1
                r[j][num] = 1
                k[k_index][num] = 1
            }
        }
    }

    dfs(board,l,r,k,0,0)
};
/* 
 * board array [][] 结果数组
 * l array 数组,存每行数据的数字,用来快速查找每一行不存在的数字
 * r array 数组,存每列数据的数字,用来快速查找每一列不存在的数字
 * k array 数组,存每3x3块的数字,用来快速查找每一块不存在的数字
 * i_index number 行定位,快速定位
 * j_index number 列定位,快速定位
 */
function dfs(board,l,r,k,i_index,j_index){
    for(let i=i_index;i<board.length;i++){
        for(let j=j_index;j<board[i].length;j++){
            let num = board[i][j]
            let h = Math.floor((i)/3); 
            let m = Math.floor((j)/3); 
            let k_index = m+(h*3)

            !l[i] ? l[i] = {}:null;
            !r[j] ? r[j] = {}:null;
            !k[k_index] ? k[k_index]  = {}:null;

            if(num=='.'){
                let resultNum = findNum(l[i],r[j],k[k_index])
                if(resultNum.length == 0){
                    return false
                }
                for(let p = 0;p<resultNum.length;p++){
                    let num = resultNum[p];
                    
                    board[i][j] = num;
                    l[i][num] =  1
                    r[j][num] = 1
                    k[k_index][num] = 1
                    let dd = dfs(board,l,r,k,i,j)
                    if(dd){
                        return dd
                    }else{
                        board[i][j] = '.'
                        l[i][num] =  0
                        r[j][num] = 0
                        k[k_index][num] = 0
                    }
                }

                return false
            }
        }
        j_index=0
    }
    return board
}

function findNum(l_obj,r_obj,k_oj){
    let result = []
    for(let i=1;i<=9;i++){
         if(!l_obj[i] && !r_obj[i] && !k_oj[i]){
            result.push(i+'')
         }     
    }
    return result
}



// @lc code=end


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值