LeetCode 51. N-Queens(N皇后问题)

275 阅读1分钟

leetcode.com/problems/n-…

Discuss:www.cnblogs.com/grandyang/p…

The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space, respectively.

 

Example 1:

Input: n = 4
Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above

Example 2:

Input: n = 1
Output: [["Q"]]

 

Constraints:

  • 1 <= n <= 9

解法一:

经典的 N 皇后问题,在 DFS 暴力求解的基础上通过剪枝去处理。基本所有的算法书中都会包含这个问题。可能有些人对国际象棋不太熟悉,大家都知道中国象棋中最厉害的是车,横竖都能走,但是在国际象棋中还有更厉害的,就是皇后,不但能横竖走,还能走两个斜线,有如 bug 一般的存在。所以经典的八皇后问题就应运而生了,在一个 8x8 大小的棋盘上如果只能放 8 个皇后,使得两两之间不能相遇。对于这类问题,没有太简便的方法,只能使用穷举法,就是尝试所有的组合,每放置一个新的皇后的时候,必须要保证跟之前的所有皇后不能冲突,若发生了冲突,说明当前位置不能放,要重新找地方,这个逻辑非常适合用递归来做。我们可以使用一个 set 集合 cols 来保存所有皇后出现的列位置,一个 set 集合 pie 来保存皇后左斜线能走的位置,一个 set 集合 na 来保存皇后右斜线能走的位置,因为当两个点在同一条对角线上,那么二者的 i+j 和 i-j 都是一样的,利用这条性质,可以快速的判断斜线上的冲突,注意递归结束之后要重置状态,代码如下:

class Solution {
    fun solveNQueens(n: Int): List<List<String>> {
        val result = mutableListOf<MutableList<String>>()
        val cols = mutableSetOf<Int>()
        val pie = mutableSetOf<Int>()
        val na = mutableSetOf<Int>()
        dfs(n, 0, cols, pie, na, Array(n) { "" }, result)
        return result
    }

    private fun dfs(
        n: Int, level: Int, cols: MutableSet<Int>, pie: MutableSet<Int>, na: MutableSet<Int>,
        subResult: Array<String>, result: MutableList<MutableList<String>>
    ) {
        if (level >= n) {
            result.add(subResult.toMutableList())
        } else {
            for (col in 0 until n) {
                if (!cols.contains(col) && !pie.contains(level + col) &&
                    !na.contains(level - col)
                ) {
                    val charArray = CharArray(n)
                    Arrays.fill(charArray, '.')
                    charArray[col] = 'Q'
                    subResult[level] = String(charArray)
                    cols.add(col)
                    pie.add(level + col)
                    na.add(level - col)
                    dfs(n, level + 1, cols, pie, na, subResult, result)
                    cols.remove(col)
                    pie.remove(level + col)
                    na.remove(level - col)
                }
            }
        }
    }
}