Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],
 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
            
          Let's understand the problem first! On a chase board a queen can move,
The problem says, on a nxn chase board, we've to place n queens on n different places of that chase board such that no queen can attack any other queens, horizontally, vertically as well as diagonally.
The above picture of 8x8 chase board is a perfect example of an arrangement where every queens are safe from others.
The chase board can be represented by a binary matrix (two dimensional array) where 0 means no queen and 1 means queen. Initially, every position of the matrix will be placed by 0.
Create a two dimensional array to represent the board.
static int[][] board = null;
            
            Initialize the board.
    void init(int numberOfQueens) {
        this.board = new int[numberOfQueens][numberOfQueens];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                board[i][j] = 0;
            }
        }
    }
            
            Check if there's already a queen in a row.
    boolean checkIfTheresAQueenInARow(int row) {
        for (int i = 0; i < board.length; i++) {
            if (board[row][i] == 1) {
                return true;
            }
        }
        return false;
    }
            
            Check if there's already a queen in a column.
     boolean checkIfTheresAQueenInAColumn(int column) {
        for (int i = 0; i < board.length; i++) {
            if (board[i][column] == 1) {
                return true;
            }
        }
        return false;
    }
            
            Check if there's already a queen in diagonal positions.
    boolean checkIfTheresQueenDiagonally(int row, int col) {
        int rowCarry = 0;
        int columnCarry = 0;
        boolean res = false;
        while (!res) {
            if ((row - rowCarry) > -1 && (col - columnCarry) > -1) {
                if (board[row - rowCarry][col - columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row - rowCarry) > -1 && (col + columnCarry) < board.length) {
                if (board[row - rowCarry][col + columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row + rowCarry) < board.length && (col - columnCarry) > -1) {
                if (board[row + rowCarry][col - columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row + rowCarry) < board.length && (col + columnCarry) < board.length) {
                if (board[row + rowCarry][col + columnCarry] != 0) {
                    res = true;
                }
            }
            rowCarry++;
            columnCarry++;
            if (rowCarry > board.length - 1 && columnCarry > board.length - 1) {
                break;
            }
        }
        return res;
    }
            
            Check if a position is safe (There's no queen row wise, column wise and diagonally).
    boolean checkIfAPositionIsSafe(int row, int col) {
        if (checkIfTheresAQueenInARow(row)) {
            return false;
        }
        if (checkIfTheresAQueenInAColumn(col)) {
            return false;
        }
        if (checkIfTheresQueenDiagonally(row, col)) {
            return false;
        }
        return true;
    }
            
            Solve the problem by backtracking.
    private void solveNQueensHelper(int row) {
        if (row == board.length) {
            listToReturn.add(print());
        } else {
            for (int col = 0; col < board.length; col++) {
                if (checkIfAPositionIsSafe(row, col)) {
                    board[row][col] = 1;
                    row += 1;
                    solveNQueensHelper(row);
                    row = row - 1;
                    board[row][col] = 0;
                }
            }
        }
    }
            
            
class Solution {
    static int[][] board = null;
    List < List < String >> listToReturn = new ArrayList < List < String >> ();
    public List < List < String >> solveNQueens(int n) {
        init(n);
        solveNQueensHelper(0);
        return listToReturn;
    }
    private void solveNQueensHelper(int row) {
        if (row == board.length) {
            listToReturn.add(print());
        } else {
            for (int col = 0; col < board.length; col++) {
                if (checkIfAPositionIsSafe(row, col)) {
                    board[row][col] = 1;
                    row += 1;
                    solveNQueensHelper(row);
                    row = row - 1;
                    board[row][col] = 0;
                }
            }
        }
    }
    List < String > print() {
        List < String > individualMatch = new ArrayList < > ();
        for (int i = 0; i < board.length; i++) {
            StringBuffer sb = new StringBuffer();
            for (int j = 0; j < board.length; j++) {
                if (board[i][j] == 1) {
                    sb.append("Q");
                } else {
                    sb.append(".");
                }
            }
            individualMatch.add(sb.toString());
        }
        return individualMatch;
    }
    void init(int numberOfQueens) {
        this.board = new int[numberOfQueens][numberOfQueens];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                board[i][j] = 0;
            }
        }
    }
    boolean checkIfTheresAQueenInARow(int row) {
        for (int i = 0; i < board.length; i++) {
            if (board[row][i] == 1) {
                return true;
            }
        }
        return false;
    }
    boolean checkIfTheresAQueenInAColumn(int column) {
        for (int i = 0; i < board.length; i++) {
            if (board[i][column] == 1) {
                return true;
            }
        }
        return false;
    }
    boolean checkIfTheresQueenDiagonally(int row, int col) {
        int rowCarry = 0;
        int columnCarry = 0;
        boolean res = false;
        while (!res) {
            if ((row - rowCarry) > -1 && (col - columnCarry) > -1) {
                if (board[row - rowCarry][col - columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row - rowCarry) > -1 && (col + columnCarry) < board.length) {
                if (board[row - rowCarry][col + columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row + rowCarry) < board.length && (col - columnCarry) > -1) {
                if (board[row + rowCarry][col - columnCarry] != 0) {
                    res = true;
                }
            }
            if ((row + rowCarry) < board.length && (col + columnCarry) < board.length) {
                if (board[row + rowCarry][col + columnCarry] != 0) {
                    res = true;
                }
            }
            rowCarry++;
            columnCarry++;
            if (rowCarry > board.length - 1 && columnCarry > board.length - 1) {
                break;
            }
        }
        return res;
    }
    boolean checkIfAPositionIsSafe(int row, int col) {
        if (checkIfTheresAQueenInARow(row)) {
            return false;
        }
        if (checkIfTheresAQueenInAColumn(col)) {
            return false;
        }
        if (checkIfTheresQueenDiagonally(row, col)) {
            return false;
        }
        return true;
    }
}