Bird
Raised Fist0
Interview PrepbacktrackinghardAmazonFacebookGoogleMicrosoft

N-Queens

Choose your preparation mode4 modes available
📋
Problem

Imagine you are organizing a chess tournament and need to place n queens on an n×n chessboard so that no two queens threaten each other. How can you arrange them safely?

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. No two queens can attack each other horizontally, vertically, or diagonally.

1 ≤ n ≤ 10Output all distinct solutions in any order
Edge cases: n = 1 → [['Q']]n = 2 → [] (no solutions)n = 3 → [] (no solutions)
</>
IDE
def solveNQueens(n: int) -> list:public List<List<String>> solveNQueens(int n)vector<vector<string>> solveNQueens(int n)function solveNQueens(n)
def solveNQueens(n):
    # Write your solution here
    pass
class Solution {
    public List<List<String>> solveNQueens(int n) {
        // Write your solution here
        return new ArrayList<>();
    }
}
#include <vector>
using namespace std;

vector<vector<string>> solveNQueens(int n) {
    // Write your solution here
    return {};
}
function solveNQueens(n) {
    // Write your solution here
}
0/9
Common Bugs to Avoid
Wrong: [["Q...","Q...","Q...","Q..."]]Placing multiple queens in the same column or row without pruning.✅ Add checks to ensure only one queen per row and column; prune columns already used.
Wrong: [["....","....","....","...."]]Returning empty boards or not placing any queens.✅ Ensure backtracking places queens and appends valid boards to solutions.
Wrong: [[".Q..","Q...","..Q.","...Q"]]Incorrect diagonal conflict checks allowing attacking queens.✅ Check both major and minor diagonals for conflicts before placing a queen.
Wrong: Partial or fewer solutions than expected for n=8 or n=10Greedy approach or incomplete backtracking pruning.✅ Implement full backtracking with column and diagonal pruning to explore all solutions.
Wrong: Timeout or no output for n=10Inefficient brute force without pruning or memoization.✅ Use pruning of columns and diagonals and consider bitmask optimization to reduce complexity.
✓
Test Cases
t1_01basic
Input4
Expected[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]

There are two distinct ways to place 4 queens so that none attack each other.

t1_02basic
Input5
Expected[["Q....","..Q..","....Q",".Q...","...Q."],["Q....","...Q.",".Q...","....Q","..Q.."],[".Q...","...Q.","Q....","..Q..","....Q"],[".Q...","....Q","..Q..","Q....","...Q."],["..Q..","Q....","...Q.",".Q...","....Q"],["..Q..","....Q",".Q...","...Q.","Q...."],["...Q.","Q....","..Q..","....Q",".Q..."],["...Q.",".Q...","....Q","..Q..","Q...."],["....Q",".Q...","...Q.","Q....","..Q.."],["....Q","..Q..","Q....","...Q.",".Q..."]]

There are 10 distinct solutions for n=5 where no two queens attack each other.

t2_01edge
Input1
Expected[["Q"]]

Only one queen on a 1x1 board; trivial solution.

t2_02edge
Input2
Expected[]

No solutions exist for n=2 as queens always attack each other.

t2_03edge
Input3
Expected[]

No solutions exist for n=3 as queens always attack each other.

t3_01corner
Input8
Expectednull

Classic 8-queens problem with 92 distinct solutions.

t3_02corner
Input4
Expected[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]

Test to catch confusion between 0/1 constraints and unbounded placement of queens.

t3_03corner
Input5
Expected[["Q....","..Q..","....Q",".Q...","...Q."],["Q....","...Q.",".Q...","....Q","..Q.."],[".Q...","...Q.","Q....","..Q..","....Q"],[".Q...","....Q","..Q..","Q....","...Q."],["..Q..","Q....","...Q.",".Q...","....Q"],["..Q..","....Q",".Q...","...Q.","Q...."],["...Q.","Q....","..Q..","....Q",".Q..."],["...Q.",".Q...","....Q","..Q..","Q...."],["....Q",".Q...","...Q.","Q....","..Q.."],["....Q","..Q..","Q....","...Q.",".Q..."]]

Test to catch off-by-one errors in indexing or recursion depth.

t4_01performance
Input10
⏱ Performance - must finish in 2000ms

Test with n=10 to verify backtracking with pruning completes within time limit (O(n!)).

Practice

(1/5)
1. You need to generate all combinations of balanced parentheses pairs for a given number n. Which algorithmic approach guarantees generating only valid sequences without generating invalid ones first?
easy
A. Brute force: generate all possible sequences of '(' and ')' of length 2n, then filter valid ones
B. Backtracking with pruning: build sequences by adding '(' or ')' only when it keeps the sequence valid
C. Greedy approach: always add '(' until n is reached, then add ')' to close all opened parentheses
D. Dynamic programming: count the number of valid sequences using Catalan number formula

Solution

  1. Step 1: Understand problem constraints

    We want to generate all valid parentheses sequences without generating invalid ones first.
  2. Step 2: Analyze approaches

    Brute force generates all sequences including invalid ones, greedy fails to generate all valid sequences, DP counts sequences but does not generate them. Backtracking with pruning adds '(' or ')' only when valid, thus generating only valid sequences.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Backtracking with pruning avoids invalid sequences [OK]
Hint: Backtracking prunes invalid sequences early [OK]
Common Mistakes:
  • Thinking greedy can generate all valid sequences
  • Confusing counting with generating sequences
2. You need to find the k-th lexicographically smallest permutation of numbers from 1 to n. Which approach guarantees an optimal solution without generating all permutations explicitly?
easy
A. Use a greedy algorithm that swaps elements to reach the k-th permutation directly.
B. Compute factorial values to determine each digit's position and build the permutation directly.
C. Use dynamic programming to count permutations and reconstruct the k-th sequence.
D. Generate all permutations using backtracking and return the k-th one.

Solution

  1. Step 1: Understand the problem constraints

    The problem requires finding the k-th permutation without enumerating all permutations, which is infeasible for large n.
  2. Step 2: Identify the approach that uses factorial number system

    Using precomputed factorials, we can determine the index of each digit in the permutation directly, avoiding full enumeration.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Factorial-based direct computation is optimal and avoids timeouts [OK]
Hint: Factorials let you jump directly to the k-th permutation [OK]
Common Mistakes:
  • Thinking greedy swaps can find k-th permutation efficiently
  • Assuming DP is needed here
  • Trying to generate all permutations for large n
3. Consider the following BFS-based code snippet for removing invalid parentheses:
from collections import deque

def is_valid(s: str) -> bool:
    count = 0
    for c in s:
        if c == '(': count += 1
        elif c == ')':
            count -= 1
            if count < 0:
                return False
    return count == 0

def remove_invalid_parentheses_bfs(s: str):
    res = []
    visited = set([s])
    queue = deque([s])
    found = False

    while queue:
        size = len(queue)
        for _ in range(size):
            curr = queue.popleft()
            if is_valid(curr):
                res.append(curr)
                found = True
            if found:
                continue
            for i in range(len(curr)):
                if curr[i] not in ('(', ')'):
                    continue
                next_str = curr[:i] + curr[i+1:]
                if next_str not in visited:
                    visited.add(next_str)
                    queue.append(next_str)
    return res

print(remove_invalid_parentheses_bfs("()())()"))
What is the output of this code?
easy
A. ["()()()"]
B. ["()()()", "(())()"]
C. ["(())()"]
D. ["()())()"]

Solution

  1. Step 1: Trace BFS levels for input "()())()"

    Initial string is invalid. BFS removes one parenthesis at each position generating candidates. The first valid strings found are "()()()" and "(())()".
  2. Step 2: Confirm both valid strings are collected

    Since BFS stops adding new states after finding valid strings at current level, both minimal removal results are returned.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Both minimal valid strings are returned [OK]
Hint: BFS returns all minimal valid strings at first valid level [OK]
Common Mistakes:
  • Returning only one valid string
  • Returning original invalid string
  • Missing one minimal valid string
4. If the problem changes so that numbers can be reused multiple times in the permutation (i.e., repetition allowed), which modification to the algorithm is correct?
hard
A. Use a greedy approach to pick the smallest available number at each step until length n is reached.
B. Use the same factorial-based approach but do not remove numbers from the list after selection.
C. Modify factorial computations to account for repeated elements and use a multiset permutation formula.
D. Generate all permutations with backtracking and stop when the k-th is found, since factorial indexing no longer applies.

Solution

  1. Step 1: Understand repetition impact

    Allowing reuse breaks the factorial number system assumption because permutations count changes drastically.
  2. Step 2: Identify correct approach

    Backtracking with early stop can generate permutations with repetition and find the k-th one, as direct factorial indexing is invalid.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Factorial indexing fails with repetition; backtracking is correct fallback [OK]
Hint: Factorial indexing requires unique elements; repetition breaks it [OK]
Common Mistakes:
  • Trying to reuse factorial indexing without adjustment
  • Ignoring repetition changes permutation count
  • Assuming greedy works for k-th permutation with repetition
5. Suppose the Word Search problem is modified so that the same cell can be used multiple times in forming the word. Which modification to the backtracking algorithm correctly handles this change?
hard
A. Add a global visited set to track cells used in all paths
B. Keep marking visited cells but reset them after each recursion
C. Remove the in-place marking of visited cells to allow reuse
D. Use dynamic programming to store partial results and avoid recomputation

Solution

  1. Step 1: Understand new constraint

    Cells can be reused multiple times, so marking visited cells to prevent reuse is no longer needed.
  2. Step 2: Modify algorithm accordingly

    Removing in-place marking allows revisiting cells, correctly reflecting the relaxed constraint.
  3. Step 3: Evaluate other options

    Keeping marking or using global visited set prevents reuse incorrectly; DP is not suitable here.
  4. Final Answer:

    Option C -> Option C
  5. Quick Check:

    Removing visited marking enables cell reuse as required [OK]
Hint: Relaxing constraints often means removing pruning steps [OK]
Common Mistakes:
  • Keeping visited marking, causing false negatives
  • Adding unnecessary global state
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard