JavaScript|LeetCode|搜索|37.解数独

本文介绍了一种使用JavaScript解决LeetCode上的37题——解数独的方法。主要思路是通过回溯算法,遍历数独中的空白格,尝试填充1到9的数字,并检查每一项是否符合行、列和3x3宫格内数字不重复的规则。如果填充的数字不合法,则回溯到上一步,继续寻找正确答案。
摘要由CSDN通过智能技术生成

法1:回溯
想法:

  1. 遍历数独中每一个空白格,依次填入1~9,每一次填入都要检验其合法性(即行、列、3×3宫不重复),不合法则变回’.’(对当前空白格填入1到9均不合法,则说明前面的有些空白格填错了,回溯),合法则进入下一阶段
  2. 从上一个填的空白格所在行开始检索(前面的行已经填了),与步骤1相同,依次填入1~9,合法则继续进行下一阶段,不合法则回溯
/** 
* @param {character[][]} board 
* @return {void} Do not return anything, modify board in-place instead. 
*/
var solveSudoku = function(board) {    
    backtrack(board, 0);
};

function backtrack(board, r) {    
    var i = r, j = 0, k = 0;    
    var character = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];    
    for(; i < 9; i++) {        
        for(j = 0; j < 9; j++) {            
            if(board[i][j] == '.') {                
                for(k = 0; k < 9; k++) {                    
                    board[i][j] = character[k];                    
                    if(!valid(board, i, j)) {                        
                        board[i][j] = '.';                        
                        continue;                    
                    }                    
                    if(!backtrack(board, i)) { // 如果没有合适的数可以满足剩余空格的规则                        
                        board[i][j] = '.'; // 回溯,试试下一个数                    
                    }                    
                    else {                        
                        return true;                    
                    }                
                }                
                if(board[i][j] == '.') {                    // 1~9 没有合适的数可填入                    
                    return false;                
                }            
            }        
        }    
    }    
    return true;
}

function valid(board, r, c) { 
    // 检测填入一个数之后,整个board是否符合条件    
    // 每行,每列,3×3    
    var i = 0, j = 0;    
    var row = [], col = [];    
    var temp1 = Math.floor(r / 3) * 3, temp2 = Math.floor(c / 3) * 3;    
    var obj = {'1' : 0, '2' : 0, '3' : 0, '4' : 0, '5' : 0, '6': 0, '7' : 0, '8' : 0, '9' : 0};
    // 记录3×3宫中出现的数字的次数
    
    for(i = 0; i < 9; i++) {        
        row[i] = board[r][i];        
        col[i] = board[i][c];    
    }
    for(j = 0; j < 9; j++) { // 行,列        
        if(row[j] != '.') {            
            if(row.indexOf(row[j], j + 1) > j) {                
                return false;            
            }        
        }        
        if(col[j] != '.') {            
            if(col.indexOf(col[j], j + 1) > j) {                
                return false;            
            }        
        }    
    }
    for(i = temp1; i < temp1 + 3; i++) { // 3 × 3的行        
        for(j = temp2; j < temp2 + 3; j++) { // 3 × 3的列            
            if(board[i][j] != '.') {                
                obj[board[i][j]]++;            
            }        
        }    
    }
    for(var x in obj) {        
        if(obj[x] > 1) {            
            return false;        
        }    
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值