n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4 输出: 2 解释: 4 皇后问题存在如下两个不同的解法。 [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ]
class Solution {
public:
int totalNQueens(int n) {
int ret=0;
if(n==0)return ret;
//第一位保存当前行最大可填充位置选择数目
//第二位保存当前行已填充次数
//第三位保存当前行填充位置
vector<vector<int>> state(n,vector<int>(3,-1));
state[0][0]=n;
state[0][1]=0;
//n*n的棋盘,一颗棋子填充进入后, 位置斜向下对角线和正下方同一列 计数+1
//上一次填充完毕后,当前行计数为0的位置可填充棋子
vector<vector<int>> board(n,vector<int>(n,0));
while(1)
{
int pos=n-1;
for(;pos>=0;pos--)
{//查找初始填充位置
if(state[pos][0]>0&&state[pos][1]<state[pos][0])
{
break;
}
}
if(pos<0)
{//填充完毕
break;
}
else
{
if(state[pos][1]>0)
{//清除记录
for(int i=pos,j=state[pos][2];i<n&&j>=0;i++,j--)
{//左斜
board[i][j]--;
}
for(int i=pos+1,j=state[pos][2]+1;i<n&&j<n;i++,j++)
{//右斜
board[i][j]--;
}
for(int i=pos+1;i<n;i++)
{
board[i][state[pos][2]]--;
}
}
int find=0;
for(int i=state[pos][2]+1;i<n;++i)
{
if(board[pos][i]==0)
{
state[pos][1]++;
state[pos][2]=i;
find=1;
//更新记录
for(int k=pos,j=state[pos][2];k<n&&j>=0;k++,j--)
{//左斜
board[k][j]++;
}
for(int k=pos+1,j=state[pos][2]+1;k<n&&j<n;k++,j++)
{//右斜
board[k][j]++;
}
for(int k=pos+1;k<n;k++)
{//正下
board[k][state[pos][2]]++;
}
break;
}
}
if(!find)
{
state[pos][0]=0;
state[pos][1]=0;
state[pos][2]=0;
continue;
}
for(int k=pos+1;k<n;k++)
{//初始化pos+1至n-1
if(state[k][1]>0)
{
for(int i=k,j=state[k][2];i<n&&j>=0;i++,j--)
{//左斜
board[i][j]--;
}
for(int i=k+1,j=state[k][2]+1;i<n&&j<n;i++,j++)
{//右斜
board[i][j]--;
}
for(int i=k+1;i<n;i++)
{//正下
board[i][state[k][2]]--;
}
}
state[k][0]=0;
state[k][1]=0;
state[k][2]=0;
}
for(int k=pos+1;k<n;k++)
{
state[k][0]=n-k;
find=0;
for(int i=0;i<n;++i)
{
if(board[k][i]==0)
{
state[k][1]++;
state[k][2]=i;
find=1;
//更新记录
for(int g=k,j=state[k][2];g<n&&j>=0;g++,j--)
{//左斜
board[g][j]++;
}
for(int g=k+1,j=state[k][2]+1;g<n&&j<n;g++,j++)
{//右斜
board[g][j]++;
}
for(int g=k+1;g<n;g++)
{//正下
board[g][state[k][2]]++;
}
break;
}
}
if(!find)
{//无法找到放置位置,退出pos+1循环
state[k][0]=0;
break;
}
}
if(state[n-1][1]==1)
{
ret++;
}
}
}
return ret;
}
};
执行用时 : 8 ms, 在N-Queens II的C++提交中击败了90.42% 的用户
内存消耗 : 8.8 MB, 在N-Queens II的C++提交中击败了28.07% 的用户
1.这题就没有多想了,直接在上个问题的基础上把返回值变成总数目