36.有效的数独

/**
 * 请你判断一个 9 x 9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
 
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 '.' 表示。
 */
/**
 * @param {character[][]} board
 * @return {boolean}
 */
var isValidSudoku = function (board) {
    // 验证每一行
    for (var i = 0; i < 9; i++) {
        var map = {}
        for (var j = 0; j < board[i].length; j++) {
            if (board[i][j] === '.') {
                continue
            }
            if (map[board[i][j]]) {
                return false
            } else {
                map[board[i][j]] = 1
            }
        }
    }
    // 验证每一列
    for (var i = 0; i < 9; i++) {
        var map = {}
        for (var j = 0; j < board[i].length; j++) {
            if (board[j][i] === '.') {
                continue
            }
            if (map[board[j][i]]) {
                return false
            } else {
                map[board[j][i]] = 1
            }
        }
    }
    // 验证9个区域,从下标1开始算直观一些
    /**
     * 区域一为 b[1][1]-b[3][3]
     * 区域二为 b[1][4]-b[3][6]
     * 区域三为 b[1][7]-b[3][9]
     * 区域四为 b[4][1]-b[6][3]
     * 区域五为 b[4][4]-b[6][6]
     * 区域六为 b[4][7]-b[6][9]
     * 区域七为 b[7][1]-b[9][3]
     * 区域八为 b[7][4]-b[9][6]
     * 区域九为 b[7][7]-b[9][9]
     */
    function between(value, range) {
        return value >= range[0] && value <= range[1]
    }
    var mapArr = new Array(9).fill(0).map(() => ({}))
    for (var i = 0; i < 9; i++) {
        for (var j = 0; j < 9; j++) {
            let value = board[i][j]
            if (value === '.') {
                continue
            }
            let rowIndex = i + 1
            let colIndex = j + 1
            // 区域1
            if (between(rowIndex, [1, 3]) && between(colIndex, [1, 3])) {
                mapArr[0][value] = (mapArr[0][value] || 0) + 1
            }
            // 区域2
            if (between(rowIndex, [1, 3]) && between(colIndex, [4, 6])) {
                mapArr[1][value] = (mapArr[1][value] || 0) + 1
            }
            // 区域3
            if (between(rowIndex, [1, 3]) && between(colIndex, [7, 9])) {
                mapArr[2][value] = (mapArr[2][value] || 0) + 1
            }
            // 区域4
            if (between(rowIndex, [4, 6]) && between(colIndex, [1, 3])) {
                mapArr[3][value] = (mapArr[3][value] || 0) + 1
            }
            // 区域5
            if (between(rowIndex, [4, 6]) && between(colIndex, [4, 6])) {
                mapArr[4][value] = (mapArr[4][value] || 0) + 1
            }
            // 区域6
            if (between(rowIndex, [4, 6]) && between(colIndex, [7, 9])) {
                mapArr[5][value] = (mapArr[5][value] || 0) + 1
            }
            // 区域7
            if (between(rowIndex, [7, 9]) && between(colIndex, [1, 3])) {
                mapArr[6][value] = (mapArr[6][value] || 0) + 1
            }
            // 区域8
            if (between(rowIndex, [7, 9]) && between(colIndex, [4, 6])) {
                mapArr[7][value] = (mapArr[7][value] || 0) + 1
            }
            // 区域9
            if (between(rowIndex, [7, 9]) && between(colIndex, [7, 9])) {
                mapArr[8][value] = (mapArr[8][value] || 0) + 1
            }
        }
    }

    for (var i = 0; i < mapArr.length; i++) {
        for (let key in mapArr[i]) {
            if (mapArr[i][key] > 1) {
                return false
            }
        }
    }

    return true
};

var board =
    [["5", "3", ".", ".", "7", ".", ".", ".", "."]
        , ["6", ".", ".", "1", "9", "5", ".", ".", "."]
        , [".", "9", "8", ".", ".", ".", ".", "6", "."]
        , ["8", ".", ".", ".", "6", ".", ".", ".", "3"]
        , ["4", ".", ".", "8", ".", "3", ".", ".", "1"]
        , ["7", ".", ".", ".", "2", ".", ".", ".", "6"]
        , [".", "6", ".", ".", ".", ".", "2", "8", "."]
        , [".", ".", ".", "4", "1", "9", ".", ".", "5"]
        , [".", ".", ".", ".", "8", ".", ".", "7", "9"]]

// console.log(isValidSudoku(board));

var board2 = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]

console.log(isValidSudoku(board2));