难度:困难
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
提示:
题目分析:
本质上还是回溯法,这里我们先建立一个数组存放0~n-1,其实也就是皇后在每一行的位置。然后进行一个全排列,去判断该全排列是否符合要求即可。因为我们利用一维数组作为存放皇后的位置,所以只要判断斜对角线上是否满足条件即可。
参考代码:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <deque>
#include <stack>
#include <algorithm>
#include <map>
using namespace std;
class Solution {
public:
int my_count = 0;
vector<string> res;
vector<vector<string>> result;
vector<vector<string>> solveNQueens(int n)
{
if (n < 1)
return result;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = i;
}
str_pl(arr, n, 0);
return result;
}
bool is_q(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
//i-j或者j-i对应的是高度,arr[i] - arr[j]对应的是宽度,
//当这个高度和宽度相等时,说明在同一对角线上,是不行的
if (abs(i - j) == abs(arr[i] - arr[j]))
return false;
}
}
return true;
}
void str_pl(int* arr, int n, int index)
{
//结束条件,说明已经排列好了
if (index == n)
{
//先检查这个排列是否符合条件
if (is_q(arr, n))
{
string temp;//建立一个临时字符串用于存放类似于‘Q...’的字符串
for (int y = 0; y < n; y++)//遍历排列数组,每个位置代表皇后的位置
{
for (int x = 0; x < n; x++)//没有到皇后的位置就填‘.’
{
if (x == arr[y])
temp += "Q";
else
temp += ".";
}
res.push_back(temp);
temp.clear();
}
//把所有的解法存起来
if (res.size() == n)
{
result.push_back(res);
res.clear();
}
}
}
else
{
for (int p = index; p < n; p++)
{
swap(arr[p], arr[index]);
str_pl(arr, n, index + 1);
swap(arr[p], arr[index]);
}
}
}
};
int main(void)
{
Solution my_class;
my_class.solveNQueens(4);
system("pause");
return 0;
}