37. 解数独
Posted lgz0921
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了37. 解数独相关的知识,希望对你有一定的参考价值。
题目链接:https://leetcode-cn.com/problems/sudoku-solver/
吐槽:自己好久没写递归了,导致这个题让我的周末很不愉快~~,都他喵快写了3个小时~~,也与自己对kotlin不熟悉有关~~
思路:就是递归~~先说明一下坑点(借助代码里的内容说明):
1. flag,题目明确说明只有一个结果。有结果就结束递归!!!!之前打ACM的时候都是有结果就输出,现在知道,其实程序输出结果后还在继续运行,如果不停止,就会导致最后内存中的board不是自己想要的结果~~~
2.题目中的colValue和rowValue是自己加上的,因为kotlin的语法特性导致传的值都是val类型不能修改,但是不能写成Solution的成员变量,这样会导致,多次递归沿用的是同一个colValue和rowValue的值
3.注意如果之前已经填过值,记得接着递归下去,否则递归停止,也不是自己想要的结果。这个坑点跟我的个人写法有关系~~~
主要思路就是:signRow标记行有哪儿个数字被用过了([行][数]),signCol标记列有哪儿个数字被用过了([列][数]),signCell标记小的正方形有哪儿个数字被用过了([小正方形][数]),小正方形的表示方法: /3 的意思是小正方形的表示就是 3*3 的一共有9个小正方形~~~。标记讲完了。接下来就是搜索,就是按行填,每填出一个符合条件的,就接着往下搜。当一行结束,跳到下一行,直到搜完。最后flag标记一下搜完,搜完就是所有的填的数字都满足条件了。然后判断一下,告诉程序不用后面的搜索了,直接return~~~
上代码:
class Solution {
private val signRow = Array(9) { BooleanArray(9) }
private val signCol = Array(9) { BooleanArray(9) }
private val signCell = Array(3) { Array(3) { BooleanArray(9) } }
private var flag = false
private fun sign(board: Array<CharArray>) {
for (i in 0 until 9) {
for (j in 0 until 9) {
if (board[i][j] != '.') {
signRow[i][(board[i][j] - '0') - 1] = true
signCol[j][(board[i][j] - '0') - 1] = true
signCell[i / 3][j / 3][(board[i][j] - '0') - 1] = true
}
}
}
}
private fun dfs(board: Array<CharArray>, row: Int, col: Int) {
var colValue = col
var rowValue = row
if (colValue == 9) {
colValue = 0
rowValue++
}
if (rowValue == 9) {
flag = !flag
return
}
if (board[rowValue][colValue] != '.') {
dfs(board, rowValue, colValue + 1)
}
for (value in 1..9) {
if (board[rowValue][colValue] == '.' && !signRow[rowValue][value - 1] && !signCol[colValue][value - 1] && !signCell[rowValue / 3][colValue / 3][value - 1]) {
board[rowValue][colValue] = (value + '0'.toInt()).toChar()
signRow[rowValue][value - 1] = true
signCol[colValue][value - 1] = true
signCell[rowValue / 3][colValue / 3][value - 1] = true
dfs(board, rowValue, colValue + 1)
if (flag) return
board[rowValue][colValue] = '.'
signRow[rowValue][value - 1] = false
signCol[colValue][value - 1] = false
signCell[rowValue / 3][colValue / 3][value - 1] = false
}
}
}
fun solveSudoku(board: Array<CharArray>): Unit {
sign(board)
dfs(board, 0, 0)
}
}
以上是关于37. 解数独的主要内容,如果未能解决你的问题,请参考以下文章