HomeLeetcode52. N-Queens II - Leetcode Solutions

52. N-Queens II – Leetcode Solutions

Description:

The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.

Given an integer n, return the number of distinct solutions to the n-queens puzzle.

Examples:

Example 1:

Input: n = 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown.

Example 2:

Input: n = 1
Output: 1

Solution in Python:

To solve the problem of finding the number of distinct solutions to the n-queens puzzle, we can use a backtracking approach.

Python
class Solution:
    def totalNQueens(self, n: int) -> int:
        # Function to check if placing a queen at board[row][col] is valid
        def is_valid(row, col, cols, diagonals, anti_diagonals):
            if cols[col] or diagonals[row - col] or anti_diagonals[row + col]:
                return False
            return True

        # Backtracking function to place queens
        def backtrack(row, cols, diagonals, anti_diagonals):
            if row == n:  # If all queens are placed successfully
                return 1

            count = 0
            for col in range(n):
                if is_valid(row, col, cols, diagonals, anti_diagonals):
                    # Place the queen
                    cols[col] = True
                    diagonals[row - col] = True
                    anti_diagonals[row + col] = True

                    # Move to the next row
                    count += backtrack(row + 1, cols, diagonals, anti_diagonals)

                    # Remove the queen (backtrack)
                    cols[col] = False
                    diagonals[row - col] = False
                    anti_diagonals[row + col] = False

            return count

        # Initialize arrays to track columns and diagonals
        cols = [False] * n
        diagonals = [False] * (2 * n - 1)
        anti_diagonals = [False] * (2 * n - 1)

        # Start backtracking from the first row
        return backtrack(0, cols, diagonals, anti_diagonals)

Explanation:

  1. Initialization:
    • cols: A list to track if a column is occupied by a queen.
    • diagonals: A list to track if a main diagonal is under attack by a queen. The index is calculated as row - col + n - 1.
    • anti_diagonals: A list to track if an anti-diagonal is under attack by a queen. The index is calculated as row + col.
  2. Validation Function:
    • is_valid(row, col, cols, diagonals, anti_diagonals): This function checks if placing a queen at board[row][col] is valid by ensuring that the column, main diagonal, and anti-diagonal are not already under attack.
  3. Backtracking Function:
    • backtrack(row, cols, diagonals, anti_diagonals): This function tries to place a queen in each column of the current row and recursively attempts to place queens in subsequent rows.
    • Base Case: If row equals n, it means all queens are placed successfully, so we return 1.
    • Recursive Case: Iterate through each column in the current row and check if placing a queen is valid. If valid, update the tracking lists and call backtrack for the next row. After the recursive call, backtrack by resetting the tracking lists.
  4. Start Backtracking:
    • Call backtrack starting from the first row (row = 0).

This solution efficiently counts all distinct solutions to the n-queens problem using backtracking and ensures that each placement is valid by checking column, diagonal, and anti-diagonal constraints.

Solution in Javascript:

JavaScript
/**
 * @param {number} n
 * @return {number}
 */
var totalNQueens = function(n) {
    // Helper function to check if placing a queen at (row, col) is valid
    const isValid = (row, col, cols, diagonals, antiDiagonals) => {
        return !cols[col] && !diagonals[row - col + n - 1] && !antiDiagonals[row + col];
    };

    // Backtracking function to place queens
    const backtrack = (row, cols, diagonals, antiDiagonals) => {
        // If all queens are placed successfully
        if (row === n) {
            return 1;
        }

        let count = 0;
        for (let col = 0; col < n; col++) {
            if (isValid(row, col, cols, diagonals, antiDiagonals)) {
                // Place the queen
                cols[col] = true;
                diagonals[row - col + n - 1] = true;
                antiDiagonals[row + col] = true;

                // Move to the next row
                count += backtrack(row + 1, cols, diagonals, antiDiagonals);

                // Remove the queen (backtrack)
                cols[col] = false;
                diagonals[row - col + n - 1] = false;
                antiDiagonals[row + col] = false;
            }
        }
        return count;
    };

    // Initialize arrays to track columns and diagonals
    const cols = new Array(n).fill(false);
    const diagonals = new Array(2 * n - 1).fill(false);
    const antiDiagonals = new Array(2 * n - 1).fill(false);

    // Start backtracking from the first row
    return backtrack(0, cols, diagonals, antiDiagonals);
};

Solution in Java:

Java
class Solution {
    public int totalNQueens(int n) {
        // Arrays to indicate whether a column, main diagonal or anti-diagonal is occupied
        boolean[] cols = new boolean[n];
        boolean[] diagonals = new boolean[2 * n - 1];
        boolean[] antiDiagonals = new boolean[2 * n - 1];
        
        return backtrack(0, cols, diagonals, antiDiagonals, n);
    }

    // Helper function to perform backtracking
    private int backtrack(int row, boolean[] cols, boolean[] diagonals, boolean[] antiDiagonals, int n) {
        // If all queens are placed successfully, return 1 as a valid solution
        if (row == n) {
            return 1;
        }
        
        int count = 0;
        for (int col = 0; col < n; col++) {
            if (isValid(row, col, cols, diagonals, antiDiagonals, n)) {
                // Place the queen
                cols[col] = true;
                diagonals[row - col + n - 1] = true;
                antiDiagonals[row + col] = true;
                
                // Move to the next row
                count += backtrack(row + 1, cols, diagonals, antiDiagonals, n);
                
                // Remove the queen (backtrack)
                cols[col] = false;
                diagonals[row - col + n - 1] = false;
                antiDiagonals[row + col] = false;
            }
        }
        return count;
    }

    // Helper function to check if placing a queen at (row, col) is valid
    private boolean isValid(int row, int col, boolean[] cols, boolean[] diagonals, boolean[] antiDiagonals, int n) {
        return !cols[col] && !diagonals[row - col + n - 1] && !antiDiagonals[row + col];
    }
}

Solution in C#:

C#
public class Solution {
    public int TotalNQueens(int n) {
        // Arrays to indicate whether a column, main diagonal, or anti-diagonal is occupied
        bool[] cols = new bool[n];
        bool[] diagonals = new bool[2 * n - 1];
        bool[] antiDiagonals = new bool[2 * n - 1];
        
        return Backtrack(0, cols, diagonals, antiDiagonals, n);
    }

    // Helper function to perform backtracking
    private int Backtrack(int row, bool[] cols, bool[] diagonals, bool[] antiDiagonals, int n) {
        // If all queens are placed successfully, return 1 as a valid solution
        if (row == n) {
            return 1;
        }
        
        int count = 0;
        for (int col = 0; col < n; col++) {
            if (IsValid(row, col, cols, diagonals, antiDiagonals, n)) {
                // Place the queen
                cols[col] = true;
                diagonals[row - col + n - 1] = true;
                antiDiagonals[row + col] = true;
                
                // Move to the next row
                count += Backtrack(row + 1, cols, diagonals, antiDiagonals, n);
                
                // Remove the queen (backtrack)
                cols[col] = false;
                diagonals[row - col + n - 1] = false;
                antiDiagonals[row + col] = false;
            }
        }
        return count;
    }

    // Helper function to check if placing a queen at (row, col) is valid
    private bool IsValid(int row, int col, bool[] cols, bool[] diagonals, bool[] antiDiagonals, int n) {
        return !cols[col] && !diagonals[row - col + n - 1] && !antiDiagonals[row + col];
    }
}

Subscribe
Notify of

0 Comments
Inline Feedbacks
View all comments

Popular