-
-
Notifications
You must be signed in to change notification settings - Fork 100
51 solution added #207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
51 solution added #207
Conversation
Reviewer's GuideIntroduces 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)
}
Flow diagram for the N-Queens backtracking processflowchart 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"]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this 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
There was a problem hiding this 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
solvetakes 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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| while(row >= 0 && col >= 0){ | ||
| if(temp[row][col] == 'Q') return false; |
There was a problem hiding this comment.
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;
- 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);
- When placing a queen, set the corresponding entries to 1:
leftRow[col] = 1;lowerDiagonal[row + col] = 1;upperDiagonal[n - 1 + col - row] = 1;
- When removing a queen (backtracking), reset them to 0.
- Update all calls to
isSafeto pass the new arrays.
| @@ -0,0 +1,64 @@ | |||
| #include <bits/stdc++.h> | |||
There was a problem hiding this comment.
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.
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++)
Related Issues
Closes #206
By submitting this PR, I confirm that:
Summary by Sourcery
Add C++ solution for the N-Queens problem using recursion and backtracking to generate all valid board configurations.
New Features: