Skip to content

Conversation

@purrvax
Copy link
Contributor

@purrvax purrvax commented Oct 23, 2025

51.N-Queens.cpp

Intuition

The N-Queens problem is solved using recursion and backtracking by placing exactly one queen in each column, ensuring that no two queens attack each other. Since every queen must be in a unique column, we only need to check whether the current row and both diagonals are safe before placing a queen. To make this safety check instant (O(1) time), we maintain three hash arrays: one to mark which rows are already occupied, and two more to track the lower-left and upper-left to diagonals. If the chosen (row, col) position is safe according to all three, we place the queen and recursively move to the next column. If we get stuck later, we backtrack removing the queen and trying another row.
This efficient hashing approach eliminates the need to scan the entire board for conflicts, and drastically reduces time complexity from O(N³ or N⁴) to roughly O(N!), allowing us to explore all valid arrangements quickly while naturally discarding invalid ones using backtracking.

Approach

1.We place one queen per column, moving from left to right (col = 0 to n−1).
2. For each column, we try placing the queen in every possible row (row = 0 to n−1).
3. Before placing a queen at (row, col), we instantly check if it’s safe using three helper arrays:
leftrow[row] → checks if any queen is already in that row
lowerdiagonal[row + col]
upperdiagonal[n - 1 + col - row] checks diagonal

4.If the position is safe, we place the queen, mark those hashes as occupied, and move to next column using recursion.
5.If we reach col == n, it means all queens are successfully placed → we store the current board as one valid answer.
6.After exploring that path, we backtrack remove the queen and unmark the hash arrays, then try next row.
Continue this process until all possibilities are explored — storing all valid solutions.

Code Solution (C++)

    class Solution {
public:
    // Function to check if placing a queen at (row, col) is safe
    bool isSafe(int row, int col, vector<string> &temp, int n) {
        int duprow = row;
        int dupcol = col;
        // Check all columns to the left in the same row
        for (int j = 0; j < col; j++) {
            if (temp[row][j] == 'Q') return false;
        }

        // Check upper-left diagonal
        while(row >= 0 && col >= 0){
            if(temp[row][col] == 'Q') return false;
            row--;
            col--;
        }
        row = duprow;
        col = dupcol;
        // Check lower-left diagonal
        while(row < n && col >= 0){
            if(temp[row][col] == 'Q') return false;
            row++;
            col--;
        }

        return true;
    }

    // Backtracking function to place queens column by column
    void solve(int col, vector<string> temp, vector<vector<string>> &ans, int n) {
        // If all columns are filled, add current board to answer
        if (col == n) {
            ans.push_back(temp);
            return;
        }

        for (int row = 0; row < n; row++) {
            if (isSafe(row, col, temp, n)) {
                // Place queen
                temp[row][col] = 'Q';
                // Recurse for next column
                solve(col + 1, temp, ans, n); 
                // Backtrack and remove queen
                temp[row][col] = '.';        
            }
        }
    }

    // Main function to call backtracking
    vector<vector<string>> solveNQueens(int n) {
    vector<vector<string>> ans;
    vector<string> temp;
    string s(n, '.');
    for(int i = 0 ; i < n ; i++) temp.push_back(s); // FIXED

    solve(0, temp, ans, n);
    return ans;
}

};
    

Related Issues

Closes #206

By submitting this PR, I confirm that:

  • This is my original work not totally AI generated
  • I have tested the solution thoroughly on leetcode
  • I have maintained proper PR description format
  • This is a meaningful contribution, not spam

Summary by Sourcery

Add C++ solution for the N-Queens problem using recursion and backtracking to generate all valid board configurations.

New Features:

  • Implement solveNQueens function to enumerate all valid queen placements.
  • Add backtracking helper (solve) to place one queen per column and collect solutions.
  • Add isSafe helper to validate row and diagonal positions before placing a queen.

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 23, 2025

Reviewer's Guide

Introduces a complete backtracking solution for the N-Queens problem in C++, using an isSafe function to check horizontal and diagonal safety and a recursive solve function to place and backtrack queens, plus fixes board initialization.

Class diagram for the new Solution class (N-Queens)

classDiagram
class Solution {
  +bool isSafe(int row, int col, vector<string> &temp, int n)
  +void solve(int col, vector<string> temp, vector<vector<string>> &ans, int n)
  +vector<vector<string>> solveNQueens(int n)
}
Loading

Flow diagram for the N-Queens backtracking process

flowchart TD
    A["solveNQueens(n)"] --> B["Initialize empty board"]
    B --> C["Call solve(0, temp, ans, n)"]
    C --> D["For each row in current column"]
    D --> E["isSafe(row, col, temp, n)?"]
    E -- Yes --> F["Place queen at (row, col)"]
    F --> G["Recurse: solve(col+1, temp, ans, n)"]
    G --> H["Backtrack: remove queen at (row, col)"]
    E -- No --> D
    G --> I["If col == n, add board to ans"]
    I --> J["Return all solutions"]
Loading

File-Level Changes

Change Details Files
Encapsulated queen placement safety checks
  • Added horizontal-left row scan
  • Implemented upper-left diagonal loop
  • Implemented lower-left diagonal loop
51.N-Queens.cpp
Implemented recursive backtracking solver
  • Added solve() to recurse through columns
  • Defined base case to collect valid boards
  • Integrated queen placement and removal for backtracking
51.N-Queens.cpp
Initialized board representation
  • Created vector temp for n×n board
  • Populated rows with '.' via string s(n, '.')
  • Fixed board initialization loop
51.N-Queens.cpp

Assessment against linked issues

Issue Objective Addressed Explanation
#206 Provide a working C++ solution for the N-Queens problem (LeetCode 51) that finds all valid arrangements using backtracking.
#206 Include an explanation of the approach and intuition for the solution in the PR (either in code comments or PR description).
#206 Ensure the filename follows the convention '[Number]. [Problem Title].cpp' (i.e., '51.N-Queens.cpp').

Possibly linked issues

  • 36. Valid Sudoku #51: The PR's N-Queen C++ solution, approach, and intuition perfectly match the details in issue 51.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for raising the PR, the owner will be review it soon' keep patience, keep contributing>>>!!! make sure you have star ⭐ the repo

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Your description mentions O(1) safety checks using hash arrays, but the code still scans rows and diagonals in O(n); consider maintaining row/diagonal occupancy arrays or bitmasks to align with the intended constant-time checks.
  • Currently solve takes the board (temp) by value, causing a full copy at each recursion; switch to passing it by reference (and backtracking changes) to avoid expensive copies and improve performance.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Your description mentions O(1) safety checks using hash arrays, but the code still scans rows and diagonals in O(n); consider maintaining row/diagonal occupancy arrays or bitmasks to align with the intended constant-time checks.
- Currently `solve` takes the board (`temp`) by value, causing a full copy at each recursion; switch to passing it by reference (and backtracking changes) to avoid expensive copies and improve performance.

## Individual Comments

### Comment 1
<location> `51.N-Queens.cpp:11-12` </location>
<code_context>
+        int duprow = row;
+        int dupcol = col;
+        // Check all columns to the left in the same row
+        for (int j = 0; j < col; j++) {
+            if (temp[row][j] == 'Q') return false;
+        }
+
</code_context>

<issue_to_address>
**suggestion:** Redundant row check in isSafe; can be optimized.

Tracking occupied rows and diagonals with arrays allows O(1) safety checks and removes the need for scanning previous columns in the same row.

Suggested implementation:

```cpp
    // Arrays to track occupied rows and diagonals
    vector<int> leftRow, upperDiagonal, lowerDiagonal;

    // Function to check if placing a queen at (row, col) is safe in O(1)
    bool isSafe(int row, int col, int n) {
        return leftRow[row] == 0 && lowerDiagonal[row + col] == 0 && upperDiagonal[n - 1 + col - row] == 0;
    }

```

```cpp
    // Backtracking function using O(1) safety checks
    void solve(int col, vector<string> &temp, vector<vector<string>> &ans, int n) {
        if (col == n) {
            ans.push_back(temp);
            return;
        }
        for (int row = 0; row < n; row++) {
            if (isSafe(row, col, n)) {
                temp[row][col] = 'Q';
                leftRow[row] = 1;
                lowerDiagonal[row + col] = 1;
                upperDiagonal[n - 1 + col - row] = 1;
                solve(col + 1, temp, ans, n);
                temp[row][col] = '.';
                leftRow[row] = 0;
                lowerDiagonal[row + col] = 0;
                upperDiagonal[n - 1 + col - row] = 0;
            }
        }
    }

    vector<vector<string>> solveNQueens(int n) {
        vector<vector<string>> ans;
        vector<string> temp(n, string(n, '.'));
        leftRow = vector<int>(n, 0);
        lowerDiagonal = vector<int>(2 * n - 1, 0);
        upperDiagonal = vector<int>(2 * n - 1, 0);
        solve(0, temp, ans, n);
        return ans;
    }

```

You will need to remove the old `isSafe` implementation and update any calls to `isSafe` to use the new signature: `isSafe(row, col, n)`. Also, ensure that the arrays `leftRow`, `lowerDiagonal`, and `upperDiagonal` are properly initialized and used throughout the class.
</issue_to_address>

### Comment 2
<location> `51.N-Queens.cpp:16-17` </location>
<code_context>
+        }
+
+        // Check upper-left diagonal
+        while(row >= 0 && col >= 0){
+            if(temp[row][col] == 'Q') return false;
+            row--;
+            col--;
</code_context>

<issue_to_address>
**suggestion (performance):** Diagonal checks can be replaced with auxiliary arrays for efficiency.

Tracking diagonal occupancy with arrays enables constant-time checks, which is more efficient for large boards than iterating through each cell.

Suggested implementation:

```cpp
    // Function to check if placing a queen at (row, col) is safe using auxiliary arrays
    bool isSafe(int row, int col, vector<int> &leftRow, vector<int> &upperDiagonal, vector<int> &lowerDiagonal, int n) {
        // Check if the column, upper diagonal, or lower diagonal is occupied
        if (leftRow[col] || lowerDiagonal[row + col] || upperDiagonal[n - 1 + col - row])
            return false;
        return true;

```

1. You need to declare and initialize the auxiliary arrays in your main/backtracking function:
   - `vector<int> leftRow(n, 0);`
   - `vector<int> upperDiagonal(2 * n - 1, 0);`
   - `vector<int> lowerDiagonal(2 * n - 1, 0);`
2. When placing a queen, set the corresponding entries to 1:
   - `leftRow[col] = 1;`
   - `lowerDiagonal[row + col] = 1;`
   - `upperDiagonal[n - 1 + col - row] = 1;`
3. When removing a queen (backtracking), reset them to 0.
4. Update all calls to `isSafe` to pass the new arrays.
</issue_to_address>

### Comment 3
<location> `51.N-Queens.cpp:1` </location>
<code_context>
+#include <bits/stdc++.h>
+using namespace std;
+
</code_context>

<issue_to_address>
**suggestion:** Avoid using <bits/stdc++.h> for portability.

This header is not part of the C++ standard and can cause compilation issues on non-GCC compilers. Please include only the specific headers you need.

Suggested implementation:

```cpp
#include <vector>
#include <string>
using namespace std;

```

If your code uses input/output streams (e.g., `cout`, `cin`), you should also add `#include <iostream>`. If you use any algorithms (e.g., `sort`, `find`), add `#include <algorithm>`. Review the rest of your file and include only the headers you actually use.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +16 to +17
while(row >= 0 && col >= 0){
if(temp[row][col] == 'Q') return false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Diagonal checks can be replaced with auxiliary arrays for efficiency.

Tracking diagonal occupancy with arrays enables constant-time checks, which is more efficient for large boards than iterating through each cell.

Suggested implementation:

    // Function to check if placing a queen at (row, col) is safe using auxiliary arrays
    bool isSafe(int row, int col, vector<int> &leftRow, vector<int> &upperDiagonal, vector<int> &lowerDiagonal, int n) {
        // Check if the column, upper diagonal, or lower diagonal is occupied
        if (leftRow[col] || lowerDiagonal[row + col] || upperDiagonal[n - 1 + col - row])
            return false;
        return true;
  1. You need to declare and initialize the auxiliary arrays in your main/backtracking function:
    • vector<int> leftRow(n, 0);
    • vector<int> upperDiagonal(2 * n - 1, 0);
    • vector<int> lowerDiagonal(2 * n - 1, 0);
  2. When placing a queen, set the corresponding entries to 1:
    • leftRow[col] = 1;
    • lowerDiagonal[row + col] = 1;
    • upperDiagonal[n - 1 + col - row] = 1;
  3. When removing a queen (backtracking), reset them to 0.
  4. Update all calls to isSafe to pass the new arrays.

@@ -0,0 +1,64 @@
#include <bits/stdc++.h>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Avoid using <bits/stdc++.h> for portability.

This header is not part of the C++ standard and can cause compilation issues on non-GCC compilers. Please include only the specific headers you need.

Suggested implementation:

#include <vector>
#include <string>
using namespace std;

If your code uses input/output streams (e.g., cout, cin), you should also add #include <iostream>. If you use any algorithms (e.g., sort, find), add #include <algorithm>. Review the rest of your file and include only the headers you actually use.

@purrvax purrvax closed this Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

51. Added N-Queen Solution in C++

1 participant