Question Link

https://leetcode.com/problems/n-queens/

Question Description

Give a nn size of board, return all distinct solutions to the n-queens.
image.png
Input: n = 4
Output: [[“.Q..”,”…Q”,”Q…”,”..Q.”],[“..Q.”,”Q…”,”…Q”,”.Q..”]]
*Explanation:
There exist two distinct solutions to the 4-queens puzzle as shown above

Simulation

Solution 1: Backtracking

If a Queen can be placed, it must satisfy below four conditions

Condition 1 No other Queen in this row -
Condition 2 No other Queen in this column |
Condition 3 No other Queen in this diagonal /
Condition 4 No other Queen in this diagonal \

Starting with an empty chessBoard (at Status 0), we place the queen at the first position of the first row(at Status 1). At the same time, we will mark all its row, column, and diagonal \ and diagonal / to True.
Then, we place second queen at the second available position, and again mark all its row, column and diagonal positions, and so on until we get size of count to n.
For backtracking steps, we need to re mark the queen position, and its row, column and diagonal back to false.

image.png

Thus, when we trying to place Queen at position (1,2). We will mark the entire row and entire column to true first.


T
T T Q T
T
T

For diagonal, we noticed that each record of diagonal \ has equivalent substraction.
(0,0)=0, (1,1)=0, (2,2)=0, (3,3)=0
Each record of diagonal / has equivalent sum.
(2,0)=2,(1,1)=2, (0,2)=2,
Thus, we mark all the record that has row-column = curRow-curColumn and all row has row+column = curRow+curColumn to True


T T T
T T Q T
T T T
T T

Solution 2: Optimized Backtracking

The solution 1 can be optimized by having three additional 1-D array
Column Array | [0,1,2,3]
Diagonal Array / [0,1,2,3,4,5]
Diagonal Array \ [0,1,2,3,4,5]
In here, when place the Queen, we can mark the corresponding position to True

For example
When place Queen at position (1,2). We mark following position to True
Column Array

Index 0 1 2 3
T

Diagonal Array / sum of col and row

Index 0 1 2 3 4 5 6
T

Diagonal Array \ subscrtion of col and row

Index 0 1 2 3 4 5 6
T

and when doing the backtracking, we will remove the value at those three array.

Implementation

Solution 2: Backtracking

  1. public List < List < String >> solveNQueens(int n) {
  2. List < List < String >> ret = new ArrayList < > ();
  3. char[][] chessBoard = new char[n][n];
  4. for (int i = 0; i < n; i++) {
  5. for (int j = 0; j < n; j++) {
  6. chessBoard[i][j] = '.';
  7. }
  8. }
  9. boolean[] col = new boolean[n];
  10. boolean[] diag1 = new boolean[2 * n - 1];
  11. boolean[] diag2 = new boolean[2 * n - 1];
  12. backTracking(chessBoard, 0, n, ret, col, diag1, diag2);
  13. return ret;
  14. }
  15. private void backTracking(char[][] curr, int idx, int n, List < List < String >> ret, boolean[] col, boolean[] diag1, boolean[] diag2) {
  16. if (idx == n) {
  17. List < String > toAdd = new ArrayList < > ();
  18. for (int i = 0; i < n; i++) {
  19. toAdd.add(String.valueOf(curr[i]));
  20. }
  21. ret.add(toAdd);
  22. return;
  23. }
  24. for (int j = 0; j < n; j++) {
  25. if (col[j] || diag1[idx + n - j - 1] || diag2[idx + j]) {
  26. continue;
  27. }
  28. col[j] = true;
  29. diag1[idx + n - j - 1] = true;
  30. diag2[idx + j] = true;
  31. curr[idx][j] = 'Q';
  32. backTracking(curr, idx + 1, n, ret, col, diag1, diag2);
  33. curr[idx][j] = '.';
  34. col[j] = false;
  35. diag1[idx + n - j - 1] = false;
  36. diag2[idx + j] = false;
  37. }
  38. }