Backtracking algorithm -- N queen problem

Backtracking algorithm -- N queen problem

Backtracking algorithm has been bothering me for a long time. After watching the video of backtracking algorithm, I specially wrote this algorithm to deepen my impression.

General formula of backtracking algorithm

The backtracking algorithm has a general formula.

void backtrack(){
    if(Judge whether it's over){
        Add to vector in(After a correct backtracking, perform the storage operation)
        return; 
    }
    for(){
        ...
        Storage element;
        backtrack;
        Delete element;
    }
}

Of course, I can't understand it now. Just look down at the backtracking code block.

N-queens problem

N queen problem refers to a chessboard composed of a row, a column, a left slash and a right slash where queen q is located without other queen Q. See leetcode51 for specific topics:

The n queen problem studies how to place n queens in n × N's chessboard, and the Queens can't attack each other.

Give you an integer n and return the solution of all different N Queen problems.

Each solution contains a different chess placement scheme for the n-queen problem, in which 'Q' and '.' represent the queen and the vacancy respectively.

Example 1:

Input: n = 4

Output: [". Q..", "... Q", "Q...", ".. Q.], [". Q. "," Q... ","... Q ",". Q...]] explanation: as shown in the above figure, there are two different solutions to the 4 queen problem.

Source: LeetCode link: Force buckle

solution

First, create a common vector container to store the answers. (as a personal habit, you can also add a parameter in the backtrack to pass res all the time)

vector<vector<string>> ans;

Then create a chessboard:

vector<string> board(n,string(n,'.'));

Backtracking function:

    void backtrack(vector<string>& board, int row){
        if(row == board.size()){
            ans.emplace_back(board);//One backtracking completion
            return;
        }

        for(int col = 0;col < board.size();col++){
            if(!isValid(board,row,col)){
                continue;
            }
            board[row][col] = 'Q';//Storage element
            backtrack(board,row+1);
            board[row][col] ='.';//Delete element
        }
    }

Parameters:

board is a chessboard and needs to be operated. It is also a vector to be transferred to ans. Row is a row. You need to increase the number of rows by 1 every time you recurse.

Parameters depend on the code, and it is difficult for me to find out which parameters are passed down. Therefore, the parameters that need to be passed...

Storing and deleting elements:

Here is storage and deletion. In fact, generally speaking, it is to modify the board all the time, and then return to maintain the board after the whole backtracking, so as to make the board intact.

isValid is a check function. Since queen Q is placed from top to bottom by row, rows do not need to be checked, and columns and slashes down the current position do not need to be checked. Finally, just check the upper column, upper left and upper right.

    bool isValid(vector<string>& board,int row,int col){
        
        for(int i = 0;i < row;i++){
            if(board[i][col] == 'Q')//Check column
                return 0;
            if(col-row+i>=0){//Check upper left
                if(board[i][col - row + i] == 'Q')
                    return 0;
            }
            if(col+row-i<board.size()){//Check upper right
                if(board[i][col + row - i] == 'Q')
                    return 0;
            }
        }
        return 1;
    }

Full code:

class Solution {
public:
    vector<vector<string>> ans;

    bool isValid(vector<string>& board,int row,int col){
        //Check column
        for(int i = 0;i < row;i++){
            if(board[i][col] == 'Q')
                return 0;
            if(col-row+i>=0){
                if(board[i][col - row + i] == 'Q')
                    return 0;
            }
            if(col+row-i<board.size()){
                if(board[i][col + row - i] == 'Q')
                    return 0;
            }
        }
        return 1;
    }

    void backtrack(vector<string>& board, int row){
        if(row == board.size()){
            ans.emplace_back(board);
            return;
        }

        for(int col=0;col<board.size();col++){
            if(!isValid(board,row,col)){
                continue;
            }
            board[row][col] = 'Q';
            backtrack(board,row+1);
            board[row][col] ='.';
        }
    }

    vector<vector<string>> solveNQueens(int n) {
        vector<string> board(n,string(n,'.'));
        backtrack(board,0);
        return ans;
    }
};

Tags: Algorithm data structure leetcode

Posted on Sun, 19 Sep 2021 13:16:23 -0400 by NTM