在解这道题之前需要了解一下什么是回溯法。

通俗来讲,回溯法就是:当前有多个选择,我们不知道具体要选哪个,就每个都需要尝试。每一个尝试的路径连接起来会得到一个树形解。

比如说上图坐标中的 [0,2] 这个位置,通过观察,我们可以知道这个位置可以放置的数字有:1、2、4,如果我们当前位置选择放置 1,则下一个位置能够选择放置的数字有:2、6,如果我们当前位置选择放置 2,则下一个位置能够选择放置的数字有:1、6 。通过分析可以画出树形解:

37. 解数独 题解

/** * @param {character[][]} board * @return {void} Do not return anything, modify board in-place instead. */var solveSudoku = function(board) {    // 辅助函数,判断当前位置放置某个值是否可行    function isOk(i,j,val){        // 判断当前行是否已存在该数        for(let k = 0; k<9; k++){            if(board[i][k] == val) return false        }        // 判断当前列是否已存在该数        for(let k = 0; k<9; k++){            if(board[k][j] == val) return false        }        // 判断当前的3*3格中是否已存在该数        let l = Math.floor(j/3)*3, t = Math.floor(i/3)*3        for(let m = t; m < t+3; m++){            for(let n = l; n < l+3; n++){                if(board[m][n] == val) return false            }        }        return true    }    function backTrace(i,j){        if(j === 9){            // 数独已结完,返回 true            if(i === 8) return true            // 否则进入下一行            i++            j = 0        }        // 当前位置没有填数字        if(board[i][j] === '.'){            // 从 1-9 中选择满足条件的数填入            for(let val = 1; val<=9; val++){                // 如果当前数字满足条件,写入数独中                if(isOk(i,j,val)){                    board[i][j] = val + ''                    // 这条路径上如果有解,则满足条件直接返回                    if(backTrace(i,j+1)) return true                }                board[i][j] = '.'            }        }else{            // 当前位置有数字,直接进入下一格            return backTrace(i,j+1)        }        // 如果当前格既没有数字,也没有满足条件的数字能填入,        // 说明这条路径不通        return false    }    backTrace(0,0)};