题目描述(Hard)
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space respectively.
题目链接
https://leetcode.com/problems/n-queens/description/
Example 1:
Input: 4
Output: [
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
算法分析
设置一个数组vector<int>C(n, 0), C[i]表示第i行皇后所在的列编号,即在位置(i, C[i])上放了一个皇后,这样用一个一维数组就能记录整个棋盘。
方法一:对当前行,每次逐列扫描,判断所在位置是否放置皇后(前面的行的皇后是否冲突),判断条件,对第i行: 1.是否在同一列C[i]==col;2.是否在同一对角线abs(row-i)==abs(col-C[i]),即两点不构成正方形,就不在一条对角线上。时间复杂度,空间复杂度。
方法二:记录皇后已经占据的列,占据的主对角线、副对角线,对N×N的棋盘,主对角线和副对角线各2N-1条。对第row行,第i列数据,其所在主对角线位置为row-j+N-1,其所在副对角线的位置为row+j。时间复杂度,空间复杂度。
提交代码(方法一):
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> result;
vector<int> C(n, -1);
dfs(result, C, 0);
return result;
}
void dfs(vector<vector<string>> &result, vector<int> &C, int row) {
const int N = C.size();
if (row == N) {
vector<string> solution;
for (int i = 0; i < N; ++i) {
string S(N, '.');
S[C[i]] = 'Q';
solution.push_back(S);
}
result.push_back(solution);
return;
}
// 逐列扫描
for (int i = 0; i < N; ++i) {
if (!isValid(C, row, i)) continue;
C[row] = i;
dfs(result, C, row + 1);
C[row] = -1;
}
}
bool isValid(vector<int>& C, int row, int col) {
for (int i = 0; i < row; ++i) {
// 如果在相同列
if (C[i] == col) return false;
// 在对角线上
if (abs(row - i) == abs(col - C[i])) return false;
}
return true;
}
};
提交代码(方法二):
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
columns = vector<bool>(n, false);
main_diag = vector<bool>(2 * n - 1, false);
anti_diag = vector<bool>(2 * n - 1, false);
vector<vector<string>> result;
vector<int> C(n, -1);
dfs(result, C, 0);
return result;
}
private:
vector<bool> columns;
vector<bool> main_diag;
vector<bool> anti_diag;
void dfs(vector<vector<string>> &result, vector<int> &C, int row) {
const int N = C.size();
if (row == N) {
vector<string> solution;
for (int i = 0; i < N; ++i) {
string S(N, '.');
S[C[i]] = 'Q';
solution.push_back(S);
}
result.push_back(solution);
return;
}
// 逐列扫描
for (int i = 0; i < N; ++i) {
bool valid = !columns[i] && !main_diag[row - i + N - 1]
&& !anti_diag[row + i];
if (!valid) continue;
columns[i] = main_diag[row - i + N - 1]
= anti_diag[row + i] = true;
C[row] = i;
dfs(result, C, row + 1);
C[row] = -1;
columns[i] = main_diag[row - i + N - 1]
= anti_diag[row + i] = false;
}
}
};