Leetcode Difficulty - N Queens, N Queens II, Eight Queens (simple recursion)

(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

insert image description here

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.

Guess you like

Origin blog.csdn.net/m0_52212261/article/details/128960290