经典的八皇后问题,在一个米字中不能有两个皇后。老办法进行深搜逐行遍历,找到 n - 1行表明找到一个可行解,否则如果放置了一个元素A导致下面一行无法进行放置,先恢复状态 移除该元素A,尝试将A 放置到该行的其他位置,继而继续遍历。整理为伪代码即
1 2 3 4 5 6 7 8 9 10 11
fun backtrack(row) { for (col in 0 until n) if (isUnderAttack(row, col))//如果该位置不能放 Queue 直接 continue continue; addQueen(row, col) if (row == n) addResult() else backtrack(row + 1) removeQueen(row, col) }
funsolveNQueens(n: Int): List<List<String>> { this.n = n res = mutableListOf() rows = BooleanArray(n) queens = IntArray(n) mainDig = BooleanArray(3 * n)//声明为3n是因为后面需要对 row - column 的结果进行放大为正数 secDig = BooleanArray(2 * n - 1) backTrack(0) return res }
privatefunbackTrack(row: Int) { for (col in0 until n) { if (isUnderAttack(row, col)) { continue//切记是 continue,并非是 return。因为后续的列可能存在满足条件的元素 } addQueen(row, col) if (row == n - 1) { addRes() } else { backTrack(row + 1) } removeQueen(row, col) } }
privatefunaddRes() { val rowString = mutableListOf<String>() for (row in0 until n) { val string = StringBuilder() for (col in0 until queens[row]) string.append('.') string.append('Q') for (col in queens[row] + 1 until n) string.append('.') rowString.add(string.toString()) } res.add(rowString) }