跳至主要內容

52. N-Queens II


52. N-Queens IIopen in new window

🔴   🔖  回溯  🔗 LeetCodeopen in new window

题目

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 the number of distinct solutions to the n-queens puzzle.

Example 1:

Input: n = 4

Output: 2

Explanation: There are two distinct solutions to the 4-queens puzzle as shown.

Example 2:

Input: n = 1

Output: 1

Constraints:

  • 1 <= n <= 9

题目大意

解题思路

这道题和 第 51 题 解题思路一样,可以采用递归和回溯来解决,通过检查每一行、每一列和每一对角线上是否存在其他皇后,来保证 N 皇后的问题得到解。只不过这道题只需要返回正确解的个数,因此 res 用一个数字记录即可。

  1. 使用一个一维数组 queens 来表示每一行皇后所在的列位置。其中 queens[i] 表示第 i 行的皇后所在的列。

  2. 使用回溯法,逐行放置皇后。在每一行,尝试将皇后放在该行的每一列,检查在当前位置 (row, col) 放置皇后是否满足不互相攻击的条件:

    • queens[i] === col:检查同一列上是否有其他皇后;
    • queens[i] - i === col - row:通过检查横坐标减去纵坐标的差是否相等,检查在左上至右下的对角线上是否有其他皇后;
    • queens[i] + i === col + row:通过检查横坐标加上纵坐标的和是否相等,检查在左下至右上的对角线上是否有其他皇后;
    • 如果以上三个条件都不满足,说明当前位置是安全的,找到了一个合适的位置。
  3. 如果找到一个合适的位置,将该位置的列坐标存入 queens 数组中,并递归调用下一行的放置皇后操作。

  4. 如果在某一行无法找到合适的位置,则需要回溯,即回到上一行,尝试在上一行的其他列放置皇后,继续递归搜索。

  5. 当成功放置 N 个皇后时,将当前 res 加一。

  6. 最后,返回最终的个数 res

代码

/**
 * @param {number} n
 * @return {string[][]}
 */
var solveNQueens = function (n) {
	let res = 0;
	let queens = new Array(n).fill(-1);

	const valid = (row, col) => {
		for (let i = 0; i < row; i++) {
			if (
				// 检查同一列上是否有其他皇后
				queens[i] == col ||
				// 检查在左上至右下的对角线上是否有其他皇后
				queens[i] - i == col - row ||
				// 检查在左下至右上的对角线上是否有其他皇后
				queens[i] + i == col + row
			) {
				return false;
			}
		}
		return true;
	};

	const backtrack = (row) => {
		if (row == n) {
			// 找到一个成功解
			res += 1;
			return;
		}

		for (let col = 0; col < n; col++) {
			if (valid(row, col)) {
				// 在当前位置放置皇后
				queens[row] = col;
				// 继续尝试下一行
				backtrack(row + 1);
				// 回溯,清空当前行状态
				queens[row] = -1;
			}
		}
	};

	backtrack(0);
	return res;
};

相关题目

相关题目
- [51. N 皇后](https://leetcode.com/problems/n-queens)