【LeetCode】51. N Queen

1. Title

The n queen problem studies how to place n queens on an n×n chessboard and make the queens unable to attack each other.
queens
The picture above shows a solution to the 8 Queens problem.

Given an integer n, return solutions to all different n queen problems. Each solution contains a clear pawn placement plan for the n-queen problem, in which'Q' and'.' represent the queen and the empty position respectively.

Example:

输入:4
输出:[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],
 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

prompt:

  • The queens cannot attack each other, which means that no two queens can be on the same horizontal, vertical or diagonal line.

Two, solve

1、DFS

version 1

Idea:
Given an N*N grid, start from Grid[0,0] and scan down row by row. If there is a legal position in a grid in a row, record it, and then continue to scan down.

If there is an illegal grid in the middle, it will stop, return to the next grid of the previous layer, and then scan down layer by layer. After scanning to the last line, if there is a legal position, record it.

The following is a 4*4 backtracking state tree, from reference 5. The specific backtracking process can be viewed in the video for more details.
result

Code:

public List<List<String>> solveNQueens(int n) {
    
    
	List<List<String>> res = new LinkedList<List<String>>();
	int[] usedCols = new int[n];// usedCols[i]: Column of the queen in row i
	Arrays.fill(usedCols, -1);  // 数组usedCols每个元素都填上-1
	DFS(usedCols, 0, res);
	return res;
}

void DFS(int[] usedCols, int row, List<List<String>> res) {
    
    
	int n = usedCols.length;
	if (row == n) {
    
    
		res.add(drawGrids(usedCols));
		return;
	}

	// 扫描当前行的每一列
	for (int col = 0; col < n; col++) {
    
    
		// 对该格进行判断,有效则记录并继续扫描下一行
		if (isValid(usedCols, row, col)) {
    
    
			usedCols[row] = col;
			DFS(usedCols, row + 1, res);// Move on to the next row
		}
	}
}

// Check if the column is valid to place queen for the row.
boolean isValid(int[] usedCols, int row, int col) {
    
    
	for (int i = 0; i < row; i++) {
    
    
		// 检查前面使用的行是否影响该格 (row, col)
		//                    ==> x0  - x ==      abs(y0  -  y)
		if (usedCols[i] == col || row - i == Math.abs(col - usedCols[i]))    			
			return false;
	}
	return true;
}

List<String> drawGrids(int[] usedCols) {
    
    
	List<String> res = new LinkedList<>();
	for (int i : usedCols) {
    
    
    	char[] line = new char[usedCols.length];
    	Arrays.fill(line, '.');
    	line[i] = 'Q';
    	res.add(String.valueOf(line));
	}
	return res;
}

Time complexity: O (n!) O(n!)O ( n ! ) , Where n is the number of queens.
Space complexity: O (n) O(n)O ( n )

Version 2

Idea: Same version 1.
Code:

class Solution {
    
    

    private Set<Integer> cols = new HashSet<>();
    private Set<Integer> diag1 = new HashSet<>();
    private Set<Integer> diag2 = new HashSet<>();

    public List<List<String>> solveNQueens(int n) {
    
    
        List<String> resUnit = new LinkedList<>();
        List<List<String>> res = new LinkedList<>();
        DFS(0, n, resUnit, res);
        return res;
    }

    private void DFS(int row, int n, List<String> resUnit, List<List<String>> res) {
    
    
        if (row==n) {
    
    
            res.add(new ArrayList<>(resUnit));
            return;
        }

        for(int col=0; col<n; col++) {
    
    
            if (cols.contains(col) || diag1.contains(row+col) || diag2.contains(row-col))  continue;

            char[] line = new char[n];
            Arrays.fill(line, '.');
            line[col] = 'Q';

            resUnit.add(String.valueOf(line));
            cols.add(col);
            diag1.add(row+col);
            diag2.add(row-col);

            DFS(row+1, n, resUnit, res);

            resUnit.remove(resUnit.size()-1);
            cols.remove(col);
            diag1.remove(row+col);
            diag2.remove(row-col);
        }
    }
}

Time complexity: O (n!) O(n!)O ( n ! )
Space complexity: O (n) O(n)O ( n )

Version 3

Idea: Same as version 1.
Code:

class Solution {
    
    

    boolean[] cols;
    boolean[] diag1;
    boolean[] diag2;

    public List<List<String>> solveNQueens(int n) {
    
    

        cols = new boolean[n];
        diag1 = new boolean[2*n];
        diag2 = new boolean[2*n];
        List<String> resUnit = new ArrayList<>();
        List<List<String>> res = new ArrayList<>();
        DFS(0, n, resUnit, res);
        return res;
    }

    private void DFS(int row, int n, List<String> resUnit, List<List<String>> res) {
    
    
        if (row==n) {
    
    
            res.add(new ArrayList<>(resUnit));
            return;
        }
        for (int col=0; col<n; col++) {
    
    
            if (cols[col] || diag1[row+col] || diag2[row-col+n])  continue;

            char[] line = new char[n];
            Arrays.fill(line, '.');
            line[col] = 'Q';
            
            resUnit.add(new String(line));
            cols[col]=true; diag1[row+col]=true; diag2[row-col+n]=true;

            DFS(row+1, n, resUnit, res);

            resUnit.remove(resUnit.size()-1);
            cols[col]=false; diag1[row+col]=false; diag2[row-col+n]=false;
        }
    }
}

Time complexity: O (n!) O(n!)O ( n ! )
Space complexity: O (n) O(n)O ( n )

Three, reference

1, Concise JAVA solution based on DFS
2, My easy understanding Java Solution
3, Comparably concise Java code
4, Share my JAVA DFS solution very easy to understand
5. Backtracking algorithm (converted to full permutation problem + pruning)-after the solution is relevant Question
6. N Queen
7. Initialization of array in java (Arrays.fill())
8. Conversion between String array and List in java

Guess you like

Origin blog.csdn.net/HeavenDan/article/details/108562501