携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
52. N皇后 II:
n 皇后问题 研究的是如何将 n
个皇后放置在 n × n
的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n
,返回 n 皇后问题 不同的解决方案的数量。
样例 1:
输入:
n = 4
输出:
2
解释:
如上图所示,4 皇后问题存在两个不同的解法。
样例 2:
输入:
n = 1
输出:
1
提示:
- 1 <= n <= 9
分析
- 面对这道算法题目,二当家的陷入了沉思。
- n的取值范围为1到9,可以用一个整形变量利用位运算标记是否被放置。
- n皇后的特点,每行,每列最终都会放置一个,所以我们可以一行一行的尝试(或者一列一列的尝试),每行最多尝试n次。
题解
java
class Solution {
public int totalNQueens(int n) {
return dfs(n, 0, 0, 0, 0);
}
/**
*
* @param n
* @param row 正在尝试放置的行
* @param columns 列标记
* @param diagonals1 左斜线标记
* @param diagonals2 右斜线标记
* @return
*/
private int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
if (row == n) {
// 全部成功放置,表示一次成功方案
return 1;
} else {
// 成功方案数
int count = 0;
// 还可以放置的位置
int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
// 还有可以放置的位置
while (availablePositions != 0) {
// 可以放置的位置
final int position = availablePositions & (-availablePositions);
// 标记当前位置不可以放置
availablePositions &= availablePositions - 1;
// 递归套娃尝试下一行
count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
}
return count;
}
}
}
c
int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
if (row == n) {
// 全部成功放置,表示一次成功方案
return 1;
} else {
// 成功方案数
int count = 0;
// 还可以放置的位置
int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
// 还有可以放置的位置
while (availablePositions != 0) {
// 可以放置的位置
int position = availablePositions & (-availablePositions);
// 标记当前位置不可以放置
availablePositions &= availablePositions - 1;
// 递归套娃
count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
}
return count;
}
}
int totalNQueens(int n){
return dfs(n, 0, 0, 0, 0);
}
c++
class Solution {
private:
/**
*
* @param n
* @param row 正在尝试放置的行
* @param columns 列标记
* @param diagonals1 左斜线标记
* @param diagonals2 右斜线标记
* @return
*/
int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
if (row == n) {
// 全部成功放置,表示一次成功方案
return 1;
} else {
// 成功方案数
int count = 0;
// 还可以放置的位置
int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
// 还有可以放置的位置
while (availablePositions != 0) {
// 可以放置的位置
int position = availablePositions & (-availablePositions);
// 标记当前位置不可以放置
availablePositions &= availablePositions - 1;
// 递归套娃
count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
}
return count;
}
}
public:
int totalNQueens(int n) {
return dfs(n, 0, 0, 0, 0);
}
};
python
class Solution:
def totalNQueens(self, n: int) -> int:
def dfs(row: int, columns: int, diagonals1: int, diagonals2: int) -> int:
if row == n:
# 全部成功放置,表示一次成功方案
return 1
else:
# 成功方案数
count = 0
# 还可以放置的位置
availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2))
# 还有可以放置的位置
while availablePositions != 0:
# 可以放置的位置
position = availablePositions & (-availablePositions)
# 标记当前位置不可以放置
availablePositions &= availablePositions - 1
# 递归套娃
count += dfs(row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1)
return count
return dfs(0, 0, 0, 0)
go
func totalNQueens(n int) int {
var dfs func(row, columns, diagonals1, diagonals2 int) int
dfs = func(row, columns, diagonals1, diagonals2 int) int {
if row == n {
// 全部成功放置,表示一次成功方案
return 1
} else {
// 成功方案数
count := 0
// 还可以放置的位置
availablePositions := (1<<n - 1) &^ (columns | diagonals1 | diagonals2)
// 还有可以放置的位置
for availablePositions > 0 {
// 可以放置的位置
position := availablePositions & -availablePositions
// 标记当前位置不可以放置
availablePositions &^= position
// 递归套娃
count += dfs(row+1, columns|position, (diagonals1|position)<<1, (diagonals2|position)>>1)
}
return count
}
}
return dfs(0, 0, 0, 0)
}
rust
impl Solution {
pub fn total_n_queens(n: i32) -> i32 {
fn dfs(n: i32, row: i32, columns: i32, diagonals1: i32, diagonals2: i32) -> i32 {
if n == row {
// 全部成功放置,表示一次成功方案
1
} else {
// 成功方案数
let mut count = 0;
// 还可以放置的位置
let mut availablePositions = ((1 << n) - 1) & (!(columns | diagonals1 | diagonals2));
// 还有可以放置的位置
while availablePositions != 0 {
// 可以放置的位置
let position = availablePositions & (-availablePositions);
// 标记当前位置不可以放置
availablePositions &= availablePositions - 1;
// 递归套娃
count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1)
}
count
}
}
dfs(n, 0, 0, 0, 0)
}
}
typescript
function totalNQueens(n: number): number {
const dfs = (row: number, columns: number, diagonals1: number, diagonals2: number) => {
if (row === n) {
// 全部成功放置,表示一次成功方案
return 1;
} else {
// 成功方案数
let count = 0;
// 还可以放置的位置
let availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
// 还有可以放置的位置
while (availablePositions != 0) {
// 可以放置的位置
const position = availablePositions & (-availablePositions);
// 标记当前位置不可以放置
availablePositions &= availablePositions - 1;
// 递归套娃
count += dfs(row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
}
return count;
}
}
return dfs(0,0,0,0);
};
原题传送门:https://leetcode-cn.com/problems/n-queens-ii/
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~