面试题 08.12. N皇后问题 - Kotlin 解法

设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。

注意:本题相对原题做了扩展

示例:

输入:4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],

["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/eight-queens-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

Kotlin 解决

fun main() {
    println(
        Solution().solveNQueens(4)
    )
}


class Solution {
    var N = 0 // 替代n,棋盘的大小 [0...n-1]

    var board = ArrayList()// 棋盘
    var recordList = ArrayList() // 记录皇后的位置,用于判断能否放置皇后

    private val result = ArrayList>()// 存放结果

    fun solveNQueens(n: Int): List> {
        initBoard(n) // 初始化棋盘
        _solveNQueens(0)
        return result
    }

    // 回溯法
    private fun _solveNQueens(colum: Int) {
        if (colum > N) {
            result.add(ArrayList(board.map { it.toString() }))
            return
        }

        for (row in 0..N) {// 当前colum行,遍历每一列,
            if (isPlaced(colum, row)) {
                board[colum][row] = 'Q'
                recordList.add(Point(colum, row))

                _solveNQueens(colum + 1)

                recordList.removeAt(recordList.lastIndex)
                board[colum][row] = '.'
            }
        }
    }


    // 是否满足皇后问题
    private fun isPlaced(colum: Int, row: Int): Boolean {
        if (recordList.isEmpty()) return false

        for (l in recordList) {
            if (l.row == row) return false

            if (row - (colum - l.colum) == l.row) return false

            if (row + (colum - l.colum) == l.row) return false

        }

        return true
    }

    // 初始化
    private fun initBoard(n: Int) {
        N = n - 1
        val columnElement = StringBuilder()

        // 初始化一行棋盘
        for (i in 0..N) {
            columnElement.append('.')
        }

        // 初始化整个棋盘
        for (i in 0..N) {
            board.add(StringBuilder(columnElement.toString()))
        }
    }


}

class Point constructor(var colum: Int, var row: Int) {

    override fun toString(): String {
        return "Point(colum=$colum, row=$row)"
    }
}

遇到的问题:

  1. Kotlin 传参数与Java一样是引用传递,初始化 map 时,没有 new 对象。
    解决:保存结果应该创建新对象result.add(ArrayList(map.map { it.toString() }))

你可能感兴趣的:(面试题 08.12. N皇后问题 - Kotlin 解法)