leetcode刷题笔记三十七 解数独

leetcode刷题笔记三十七 解数独

源地址:37. 解数独

问题描述:

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

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

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

代码补充:

object Solution {
    def solveSudoku(board: Array[Array[Char]]): Unit = {
        //构建对应行、列、宫的情况查询数组
        val boolRow = Array.ofDim[Boolean](9,9)
        val boolCol = Array.ofDim[Boolean](9,9)
        val boolSquarl = Array.ofDim[Boolean](9,9)
        
        //通过设置boolean型数组标记每行出现了那些数字
         for(row <- 0  until 9){
             for(col <- 0 until 9){
                 if (board(row)(col) != '.') {
                     boolRow(row)(board(row)(col)-'1') = true
                     boolCol(col)(board(row)(col)-'1') = true
                     boolSquarl(row/3 *3 + col/3)(board(row)(col)-'1') = true
                 }
             }
         }
        
        //调用回溯函数
         recall(board, 0, boolRow, boolCol, boolSquarl)
    }

    def recall(board: Array[Array[Char]], position:Int, boolRow:Array[Array[Boolean]], boolCol:Array[Array[Boolean]], boolSquarl:Array[Array[Boolean]]):Boolean = {
        var index = position
        // 过滤那些不需要填入的位置
        while( index < 81 && (board(index/9)(index%9) != '.')) index += 1

        //成功条件
        if (index < 81){
            val row = index/9
            val col = index%9
            //由于Scala中int转Char使用的ASCII码,这里使用1-9的ACSII码
            //判断当前数字没有在行、列、宫出现,出现的情况进行剪枝
            for(i <- 49 to 57 if((boolRow(row)(i-49) == false) && (boolCol(col)(i-49) == false) && (boolSquarl(row/3 *3 + col/3)(i-49) == false))){
                //println("this i:" + i.toChar)
                //进行插入
                board(row)(col) = i.toChar
                boolRow(row)(i-49) = true
                boolCol(col)(i-49) = true
                boolSquarl(row/3 *3 + col/3)(i-49) = true
                //向前推进
                if(recall(board, index+1, boolRow, boolCol, boolSquarl)) {
                    //println("boolRow: " + boolRow.mkString)
                    return true
                    }
                //当前字符位置不对,重置为'.'
                board(row)(col) = '.'
                boolRow(row)(i-49) = false
                boolCol(col)(i-49) = false
                boolSquarl(row/3 *3 + col/3)(i-49) = false
            }
            return false
        } 
        return true
    }
}

posted @ 2020-05-19 23:01  ganshuoos  阅读(147)  评论(0编辑  收藏  举报