N皇后问题
题目
n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击(每一行,每一列,每个对角线上只能有一个皇后存在)。
给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
示例 1:
输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。
思路
采用暴力搜索,回溯剪枝标记处每一个已经存放的皇后的行和列以及对角线,表示以后这些位置以后不能再放皇后了,这里可以用数组标记,我这里采用的是位运算方法。
整形int类型二进制通常有32位,可以利用这个位数的状态(二进制中只有0和1)表示是否可以放皇后,比如1表示已经放过皇后了,那么只有0可以再放皇后。比如n=5,那么最初的状态就是00000,最后结束条件就是11111,表示所有位置都放了皇后
代码
class Solution {
public:
int dfs(int limit,int col,int left,int right){
if(col==limit){
return 1;
}//这是搜索到最后一列的条件,表示找到一种方法可以放皇后,并开始返回
int ban=col|left|right;//放皇后的位置有3个限制(因为行在不断向下搜索,所以只用考虑每一列,不用考虑行),
//考虑列,左上到右下对角线(left),右上到左下对角线(right),比如列1000,left对角线0100,right对角线0010,那么|就把所有的1聚集到一起变成1110,表示只有0这个位置可以放皇后
int candiate=limit&(~ban);//先把ban取反(1变成0,0变成1),那么就是只有1的位置可以放皇后,n=5时,limit=11111,&保留了5个位内所有的1
int place=0;
int ans=0;
while(candiate!=0){//如果candiate==0表示所有位置都占满
place=candiate&(-candiate);//获得最近的一个1,比如10010,操作之后变成00010,只剩下最近的一个1,
candiate^=place;//异或操作,把放皇后的这一列标记一下
ans+=dfs(limit,(col|place),(left|place)>>1,(right|place)<<1);//这里|操作把1聚集,每一列直接标记,但是left对角线比如上一行100(第一个1不能放皇后),
//那么下一列就应该是010表示这个对角线位置不能放皇后,right对角线也是如此
}
return ans;
}
int totalNQueens(int n) {
int limit=(1<<n)-1;//比如n=5,那么limit=11111,因为int有32位但是我们只需要5位,那么就用这个值限制出来5位,其他位上的值通过&运算都可变为无效值
return dfs(limit,0,0,0);
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具