[algorithm topic] N queen problem | backtracking algorithm | simple and easy to understand, high efficiency

Queen N

Difficulty: difficulty

The n-queen problem studies how to place n queens on N × n chessboard and make them unable to attack each other.

Given an integer n, returns the solution to all the different N Queens problems.

Each solution contains a clear chess placement scheme for the n-queen problem, in which "Q" and "." represent the queen and the empty space respectively.

**Note: there are two n queens in * * leetcode, both of which are difficult. In fact, there is no difference in processing. Backtracking can be used. One is to return a List, the other is to return a number.

Here, change the topic to output: number + List. If you only need to return a List or a number, you can delete the unnecessary code, further improve efficiency and save memory.

Example:

Input: 4
 Output: 
2
[
 [". Q..", / / solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["... Q.", / / solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
#Explanation: there are two different solutions to the queen problem.

Tips:

  • Queen, yes Chess The chess pieces in mean king His wife. There's only one thing the queen does, and that's“ To eat ”. When she met a piece that she could eat, she rushed to eat it. Of course, she can walk one to seven steps horizontally, vertically and obliquely, and can move forward or backward. (quoted from Baidu Encyclopedia - Queen )

Speed of official solution

The speed of this solution (simply return to List)

Introduction to ideas

Before you can understand the problem-solving method, you need to have a certain understanding of depth first search.

Depth first search: from a vertex V0, go all the way to the end. If you find that you can't reach the target solution, go back to the previous node, and then go to the end from another path. This concept of going as far as possible to the depth is the concept of depth first.

There are three criteria to determine whether the queen can be placed in this position:

Let's assume that the coordinate is [I, J]

  1. There is no queen in this column: the coordinates of column i can be expressed directly
  2. No queen from bottom left to top right: use i + j as the subscript to judge whether there is Queen
  3. No queen from top left to bottom right: use i - j + n as the subscript to judge whether there is a queen

Note: since we are looking for the queen line by line, we don't need to judge whether there is a queen in the new line

Storage data description:

boolean[] down; //Bottom left to top right
boolean[] up;//Top left to bottom right
boolean[] col;//column
int n;
boolean[][] visited;//Is there a queen
//List version
List<List<String>> res = new ArrayList<>();
//Digital Edition
int sum = 0;

Because there are n chessboards and N Queens, each line will have a queen. First, initialize the different placement methods of the first line:

void start(int n) {
    this.n = n;
    down = new boolean[2 * n + 1];//Prevention of cross-border
    up = new boolean[2 * n + 1];//Prevention of cross-border
    col = new boolean[n + 1];
    visited = new boolean[n + 1][n + 1];
    //initialization
    Arrays.fill(down, false);
    Arrays.fill(up, false);
    Arrays.fill(col, false);
    for (int j = 1; j <= n; j++) {
        Arrays.fill(visited[j], false);
    }
    //Different ways to prevent the first line
    for (int i = 1; i <= n; i++) {
        visited[1][i] = true;
        col[i] = true;
        down[1 + i] = true;
        up[1 - i + n] = true;
        dfs(2);//Starting from the second line, keep going deep!
        visited[1][i] = false;
        col[i] = false;
        down[1 + i] = false;
        up[1 - i + n] = false;
    }
}

Next, we need to find out whether the second line can be placed. If so, continue to k+1 (the next line), and continue to search. Until line n is finished, you can modify the result to be returned

void dfs(int k) {
    if (k == n + 1) {
        //List version
        ArrayList<String> strings = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            //It's fast and good to use StringBuilder. You can have a deep understanding of the immutability of String in java
            StringBuilder s = new StringBuilder();
            for (int j = 1; j <= n; j++) {
                if (visited[i][j]) s.append('Q');
                else s.append('.');
            }
            strings.add(s.toString());
        }
        res.add(strings);
        //Digital version
        sum += 1;
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (col[i] || down[k + i] || up[k - i + n]) continue;
        visited[k][i] = true;
        col[i] = true;
        down[k + i] = true;
        up[k - i + n] = true;
        dfs(k + 1);
        visited[k][i] = false;
        col[i] = false;
        down[k + i] = false;
        up[k - i + n] = false;
    }
}

Detailed code (with input test):

You only need to delete the test module to pass the two questions of Queen N in leetcode. However, you can only write them once after understanding. It is not advisable to copy and paste them!

/***
 * @author: G_night
 * Reprint please state the author
 * Reprint please state the author
 ***/

import java.util.*;

class Solution {
    boolean[] down;
    boolean[] up;
    boolean[] col;
    int n;
    boolean[][] visited;
    //List version
    List<List<String>> res = new ArrayList<>();
    //Digital Edition
    int sum = 0;

    //Back to digital
    public int totalNQueens(int n) {
        //Initialize data and set initial location
        start(n);
        return sum;
    }

    //Return to List version
    public List<List<String>> solveNQueens(int n) {
        //Initialize data and set initial location
        start(n);
        return res;
    }

    void start(int n) {
        this.n = n;
        down = new boolean[2 * n + 1];
        up = new boolean[2 * n + 1];
        col = new boolean[n + 1];
        visited = new boolean[n + 1][n + 1];
        //initialization
        Arrays.fill(down, false);
        Arrays.fill(up, false);
        Arrays.fill(col, false);
        for (int j = 1; j <= n; j++) {
            Arrays.fill(visited[j], false);
        }
        for (int i = 1; i <= n; i++) {
            visited[1][i] = true;
            col[i] = true;
            down[1 + i] = true;
            up[1 - i + n] = true;
            dfs(2);
            //Restore false to prevent previous effects
            visited[1][i] = false;
            col[i] = false;
            down[1 + i] = false;
            up[1 - i + n] = false;
        }
    }

    void dfs(int k) {
        if (k == n + 1) {
            //List version
            ArrayList<String> strings = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
                StringBuilder s = new StringBuilder();
                for (int j = 1; j <= n; j++) {
                    if (visited[i][j]) s.append('Q');
                    else s.append('.');
                }
                strings.add(s.toString());
            }
            res.add(strings);
            //Digital version
            sum += 1;
            return;
        }
        for (int i = 1; i <= n; i++) {
            if (col[i] || down[k + i] || up[k - i + n]) continue;
            visited[k][i] = true;
            col[i] = true;
            down[k + i] = true;
            up[k - i + n] = true;
            dfs(k + 1);
            visited[k][i] = false;
            col[i] = false;
            down[k + i] = false;
            up[k - i + n] = false;
        }
    }
}

//test
class try {
    public static void main(String[] args) {
        int n=4;
        System.out.println(new Solution().totalNQueens(n));
        System.out.println(new Solution().solveNQueens(n));
    }
}

Postscript

It's just a solution, but there's a simpler way of judging (using bigmap thinking), but it's easy to think of and explain when it's easy to understand in an interview.

Tags: Java

Posted on Sun, 14 Jun 2020 02:24:52 -0400 by hnissani