Striver-SDE-Sheet

Repository containing solution for #SdeSheetChallenge by striver

View the Project on GitHub

N-Queens

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 all distinct solutions to the n-queens puzzle. You may return the answer in any order.

Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space, respectively.

Brute force backtracking (8ms-AC)

Code

class Solution {
private:
    bool isSafe(vector<string>& board, int row, int col)
    {
        int i = row, j = col;
        int n = board.size();
        while (i >= 0 && j >= 0) { // check upper left diagonal
            if (board[i][j] == 'Q')
                return false;
            i--;
            j--;
        }
        i = row;
        j = col;
        while (i >= 0 && j < n) { // check upper right diagonal
            if (board[i][j] == 'Q')
                return false;
            i--;
            j++;
        }
        for (i = 0; i < n; i++) { // check column
            if (board[i][col] == 'Q')
                return false;
        }
        return true;
    }

    void placeQueen(vector<string>& board, int row, int col)
    {
        board[row][col] = 'Q';
    }

    void removeQueen(vector<string>& board, int row, int col)
    {
        board[row][col] = '.';
    }

    void backtrackNQueen(vector<vector<string>>& res, vector<string>& board, int row)
    {
        int n = board.size();
        if (row == n) { // row index is out of bounds, we found the solution
            res.push_back(board);
            return;
        }

        for (int col = 0; col < n; col++) { // traverse every column
            if (isSafe(board, row, col)) {
                placeQueen(board, row, col); // DO
                backtrackNQueen(res, board, row + 1); // RECUR
                removeQueen(board, row, col); // UNDO
            }
        }
    }

public:
    vector<vector<string>> solveNQueens(int n)
    {
        vector<vector<string>> res;
        vector<string> board(n, string(n, '.'));
        backtrackNQueen(res, board, 0);
        return res;
    }
};

3 vectors optimized backtracking (3ms-AC)

Code

class Solution {
private:
    bool isSafe(vector<string>& board, vector<int>& colSet, vector<int>& posDig, vector<int>& negDig, int row, int col)
    {
        int n = board.size();
        if (colSet[col] || posDig[col + row] || negDig[col - row + n - 1])
            return false;
        return true;
    }

    void placeQueen(vector<string>& board, vector<int>& colSet, vector<int>& posDig, vector<int>& negDig, int row, int col)
    {
        int n = board.size();
        board[row][col] = 'Q';
        colSet[col] = 1;
        posDig[col + row] = 1;
        negDig[col - row + n - 1] = 1;
    }

    void removeQueen(vector<string>& board, vector<int>& colSet, vector<int>& posDig, vector<int>& negDig, int row, int col)
    {
        int n = board.size();
        board[row][col] = '.';
        colSet[col] = 0;
        posDig[col + row] = 0;
        negDig[col - row + n - 1] = 0;
    }

    void backtrackNQueen(vector<vector<string>>& res, vector<string>& board, vector<int>& colSet, vector<int>& posDig, vector<int>& negDig, int row)
    {
        int n = board.size();
        if (row == n) { // row index is out of bounds, we found the solution
            res.push_back(board);
            return;
        }

        for (int col = 0; col < n; col++) { // traverse every column
            if (isSafe(board, colSet, posDig, negDig, row, col)) {
                placeQueen(board, colSet, posDig, negDig, row, col); // DO
                backtrackNQueen(res, board, colSet, posDig, negDig, row + 1); // RECUR
                removeQueen(board, colSet, posDig, negDig, row, col); // UNDO
            }
        }
    }

public:
    vector<vector<string>> solveNQueens(int n)
    {
        vector<vector<string>> res; // final result
        vector<string> board(n, string(n, '.')); // chess board with "...." strings

        vector<int> colSet(n, 0); // column vector to store column indexes
        vector<int> posDig(2 * n - 1, 0); // positive diagonal vector to store (col+row) indexes
        vector<int> negDig(2 * n - 1, 0); // negative diagonal vector to store (col-row+n-1) indexes

        backtrackNQueen(res, board, colSet, posDig, negDig, 0);

        return res;
    }
};

1 vector optimized backtracking (7ms-AC)

Code

class Solution {
private:
    bool isSafe(vector<int>& flag, int n, int row, int col)
    {
        if (flag[col] == 1 || flag[n + col + row] == 1 || flag[4 * n - 2 + col - row] == 1)
            return false;
        return true;
    }
    void placeQueen(vector<string>& board, vector<int>& flag, int n, int row, int col)
    {
        board[row][col] = 'Q';
        flag[col] = 1;
        flag[n + col + row] = 1;
        flag[4 * n - 2 + col - row] = 1;
    }
    void removeQueen(vector<string>& board, vector<int>& flag, int n, int row, int col)
    {
        board[row][col] = '.';
        flag[col] = 0;
        flag[n + col + row] = 0;
        flag[4 * n - 2 + col - row] = 0;
    }
    void backtrackNQueen(vector<vector<string>>& res, vector<string>& board, vector<int>& flag, int row)
    {
        int n = board.size();
        if (row == n) {
            res.push_back(board);
            return;
        }
        for (int col = 0; col < n; col++) {
            if (isSafe(flag, n, row, col)) {
                placeQueen(board, flag, n, row, col);
                backtrackNQueen(res, board, flag, row + 1);
                removeQueen(board, flag, n, row, col);
            }
        }
    }

public:
    vector<vector<string>> solveNQueens(int n)
    {
        vector<vector<string>> res;
        vector<string> board(n, string(n, '.'));
        vector<int> flag(5 * n - 2, 0);
        backtrackNQueen(res, board, flag, 0);
        return res;
    }
};

Codestudio Solution

void nQueenHelper(int i, int n, vector<vector<int>>& board, vector<vector<int>>& ans, vector<int>& col, vector<int>& rDig, vector<int>& ldig)
{
    if (i == n) {
        vector<int> temp;
        for (vector<int> k : board) {
            for (int j = 0; j < k.size(); j++)
                temp.push_back(k[j]);
        }
        ans.push_back(temp);
        return;
    }
    for (int j = 0; j < n; j++) {
        if (col[j] == 0 && rDig[i + j] == 0 && ldig[n - 1 + i - j] == 0) {
            board[i][j] = 1;
            col[j] = rDig[i + j] = ldig[n - 1 + i - j] = 1;
            nQueenHelper(i + 1, n, board, ans, col, rDig, ldig);
            board[i][j] = 0;
            col[j] = rDig[i + j] = ldig[n - 1 + i - j] = 0;
        }
    }
}

vector<vector<int>> solveNQueens(int n)
{
    vector<vector<int>> ans;
    vector<vector<int>> board(n, vector<int>(n, 0));
    vector<int> col(n, 0);
    vector<int> rDig(2 * n - 1, 0);
    vector<int> ldig(2 * n - 1, 0);
    nQueenHelper(0, n, board, ans, col, rDig, ldig);
    return ans;
}