(I don’t know why this kind of simple recursion is always set as a difficult question. Although the optimization part is very good, the question is too good)
Question:
According to the rules of chess, the queen can attack the chess pieces on the same row or column or on the same slash.
The n queens problem studies how to place n queens on an n×n chessboard, and make the queens unable to attack each other.
Given an integer n, return all different n-queens solutions.
Each solution consists of a different pawn placement scheme for the n-queens problem, where 'Q' and '.' represent queens and open spaces, respectively.
Solution:
First look at the data range, 1 <= n <= 9, such a small data, it is estimated to be an enumeration
Then how do we enumerate it, traversing all the possible cases of the i + 1th row when the first i row has been determined
(the 0th row is all desirable for each column)
Then how do we judge whether it is advisable or not?
① The column coincides with the column of the previous row
② The column and the column of the previous row are on a slash (current row - previous row = | current column - previous column |)
Then we use a character string to express the selection column of the previous row.
For example, "13524", the first row selects the first column, the second row selects the third column...
code show as below:
class Solution {
public:
vector<string> solve(string pre, int n) {
vector<string> res;
bool flag[10];
for(int i = 0; i < n; i++) {
flag[i] = true;
}
int m = pre.size();
for(int i = 0; i < m; i++) {
flag[pre[i] - '0'] = false;
if(pre[i] - '0' - m + i >= 0) flag[pre[i] - '0' - m + i] = false;
if(pre[i] - '0' + m - i < n) flag[pre[i] - '0' + m - i] = false;
}
vector<string> temp;
for(int i = 0; i < n; i++) {
if(flag[i] && m != n - 1) {
temp = solve(pre + char(i + '0'), n);
res.insert(res.end(), temp.begin(), temp.end());
}
else if(flag[i] && m == n - 1) {
res.push_back(pre + char(i + '0'));
}
}
return res;
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string> > res;
vector<string> t = solve("", n);
for(int i = 0; i < t.size(); i++) {
vector<string> temp;
for(int j = 0; j < n; j++) {
string str = "";
for(int k = 0; k < n; k++) {
if(k != t[i][j] - '0') {
str = str + '.';
}
else {
str = str + 'Q';
}
}
temp.push_back(str);
}
res.push_back(temp);
}
return res;
}
};
Next, we consider optimizing
Do you think that this is very similar to binary displacement
We use three binary numbers to represent, on the left slash, on the right slash, and on a straight line,
each binary number represents the status of the current row
Next, every time we pass a line, we can do a binary shift once (meaning that there is no binary shift on the straight line),
so that the space and time complexity are reduced.