皇后可以横着、竖着、斜着走。也就是皇后所在的行、列、对角线不能有另一个皇后。
每行有一个皇后,一行一行进行判断当前行某位置是否可以放置,进行DFS。
有性质,若(x,y)放置了皇后,那么不可以再有一个位置(i,j),x+y == i+j || x-y == i-j
时间复杂度为O(n^3)
class Solution {
public:
vector<vector<string>> rtn;
int n;
vector<vector<string>> solveNQueens(int n) {
this->n = n;
// diff为横纵坐标差值
// sum为横纵坐标之和
// ans为Queen放置的列数
vector<int> diff, sum, ans;
findAns(ans, sum, diff);
return rtn;
}
void findAns(vector<int> &ans, vector<int> &sum, vector<int> &diff) {
if (ans.size() == n) { // 找到一种解法
vector<string> thisans;
for (int i = 0; i < n; i ++) {
string thisrow = "";
for (int j = 0; j < n ; j ++) {
thisrow += (ans[j] == i) ? "Q":".";
}
thisans.push_back(thisrow);
}
rtn.push_back(thisans);
return;
}
for (int i = 0; i < n; i ++) {
bool flag = false; // 判断当前位置是否可以放置
for (auto a:ans)
if (i == a) {
flag = true;
break;
}
if (flag) continue;
for (auto s:sum)
if (ans.size() + i == s) {
flag = true;
break;
}
if (flag) continue;
for (auto d:diff)
if (ans.size() - i == d) {
flag = true;
break;
}
if (flag) continue;
// DFS搜索
sum.push_back(ans.size()+i);
diff.push_back(ans.size()-i);
ans.push_back(i);
findAns(ans, sum, diff);
ans.pop_back();
diff.pop_back();
sum.pop_back();
}
}
};