-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #359 from dinesh-2047/rotate-array
Rotate array problem solution added
- Loading branch information
Showing
16 changed files
with
1,473 additions
and
1,033 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
...TIONS (TILL TREE & BASIC GRAPH CONCEPTS)/BACKTRACKING PROBLEMS/sudoku solver.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#LEETCODE PROBLEM 37 | ||
Problem statement :- Write a program to solve a Sudoku puzzle by filling the empty cells. | ||
|
||
A sudoku solution must satisfy all of the following rules: | ||
|
||
Each of the digits 1-9 must occur exactly once in each row. | ||
Each of the digits 1-9 must occur exactly once in each column. | ||
Each of the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid. | ||
The '.' character indicates empty cells. | ||
|
||
EXAMPLE : | ||
Input: board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]] | ||
Output: [["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] | ||
|
||
|
||
SOLUTION :- | ||
|
||
Intuition | ||
This implementation optimizes the traditional backtracking approach by incorporating pre-computed constraints and heuristic decision-making, such as selecting the cell with the fewest valid candidates first. This strategy dramatically reduces unnecessary recursive calls and improves efficiency. | ||
|
||
Approach | ||
Pre-compute Constraints: | ||
|
||
Maintain bitmasks (row, col, box) for each row, column, and 3x3 subgrid to track which numbers are already used. | ||
Collect the coordinates of all empty cells (R and C). | ||
Candidate Computation: | ||
|
||
Use a helper function cand to compute valid numbers for a given cell using bitwise operations. | ||
Calculate the number of valid candidates for each empty cell and store this information in cc. | ||
Dynamic Candidate Recalculation: | ||
|
||
Recalculate the number of valid candidates whenever a number is placed or removed during the backtracking process. This ensures the constraints are always up to date. | ||
Optimized Backtracking: | ||
|
||
Select the next cell to fill based on the cell with the fewest valid candidates (best), minimizing the branching factor. | ||
Use a bitmask to generate possible numbers efficiently and iterate through them. | ||
Perform recursive backtracking to fill cells. | ||
Pruning: | ||
|
||
If no valid candidates exist for any cell during the process, backtrack immediately. | ||
Complexity | ||
Time Complexity: | ||
|
||
The optimization significantly reduces the effective branching factor. While the theoretical worst-case time complexity remains O(9ᵐ), where m is the number of empty cells, the heuristic often lowers the practical complexity to much more manageable levels. | ||
Space Complexity: | ||
|
||
O(m) for storing empty cell positions (R and C) and candidate counts (cc), where m is the number of empty cells. | ||
|
||
|
||
|
||
|
||
CODE IN CPP :- | ||
class Solution { | ||
public: | ||
void solveSudoku(vector<vector<char>>& board) { | ||
int row[9]{}, col[9]{}, box[9]{}; | ||
vector<int> R, C, cc; | ||
for (int i = 0; i < 9; i++) { | ||
for (int j = 0; j < 9; j++) { | ||
if (board[i][j] == '.') { | ||
R.push_back(i); | ||
C.push_back(j); | ||
} else { | ||
int d = board[i][j] - '1', m = 1 << d, b = (i / 3) * 3 + j / 3; | ||
row[i] |= m; col[j] |= m; box[b] |= m; | ||
} | ||
} | ||
} | ||
cc.resize(R.size()); | ||
auto countBits = [&](int x) { int c = 0; while (x) { x &= x - 1; c++; } return c; }; | ||
function<int(int)> cand = [&](int idx) { | ||
int r = R[idx], c = C[idx], b = (r / 3) * 3 + c / 3; | ||
return countBits((~(row[r] | col[c] | box[b])) & 0x1ff); | ||
}; | ||
auto recalc = [&]() { | ||
for (int i = 0; i < (int)R.size(); i++) { | ||
if (board[R[i]][C[i]] == '.') cc[i] = cand(i); | ||
} | ||
}; | ||
for (int i = 0; i < (int)R.size(); i++) cc[i] = cand(i); | ||
function<bool(int)> dfs = [&](int filled) { | ||
if (filled == (int)R.size()) return true; | ||
int best = -1, bc = 10; | ||
for (int i = 0; i < (int)R.size(); i++) { | ||
if (board[R[i]][C[i]] == '.' && cc[i] < bc) { | ||
bc = cc[i]; best = i; | ||
if (!bc) return false; | ||
if (bc < 2) break; | ||
} | ||
} | ||
int r = R[best], c = C[best], b = (r / 3) * 3 + c / 3; | ||
int mask = (~(row[r] | col[c] | box[b])) & 0x1ff; | ||
while (mask) { | ||
int pick = mask & -mask, d = __builtin_ctz(pick); | ||
board[r][c] = d + '1'; row[r] |= pick; col[c] |= pick; box[b] |= pick; | ||
recalc(); | ||
if (dfs(filled + 1)) return true; | ||
board[r][c] = '.'; row[r] ^= pick; col[c] ^= pick; box[b] ^= pick; | ||
recalc(); | ||
mask &= mask - 1; | ||
} | ||
return false; | ||
}; | ||
dfs(0); | ||
} | ||
}; |
106 changes: 106 additions & 0 deletions
106
...RAPH CONCEPTS)/GRAPH TRAVERSAL TECHNIQUES/CODE WITH HARRY (CODES)/Kosarajus's Algorithm.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
Steps of Kosaraju's Algorithm: | ||
1. Perform a Depth First Search (DFS) on the original graph and store the nodes in a stack based on their finish times. | ||
2. Reverse the graph by transposing its adjacency matrix (reverse all edges). | ||
3. Perform DFS on the transposed graph in the order of nodes stored in the stack. | ||
4. Each DFS traversal on the transposed graph gives a strongly connected component (SCC). | ||
Uses of Kosaraju's Algorithm: | ||
- To find strongly connected components (SCCs) in a directed graph. | ||
- SCCs are useful in understanding the modular structure of graphs, deadlock detection, and other graph-related problems. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
|
||
#define MAX 1000 | ||
|
||
typedef struct Stack { | ||
int data[MAX]; | ||
int top; | ||
} Stack; | ||
|
||
void initStack(Stack* stack) { | ||
stack->top = -1; | ||
} | ||
|
||
void push(Stack* stack, int value) { | ||
if (stack->top < MAX - 1) { | ||
stack->data[++stack->top] = value; | ||
} | ||
} | ||
|
||
int pop(Stack* stack) { | ||
if (stack->top >= 0) { | ||
return stack->data[stack->top--]; | ||
} | ||
return -1; | ||
} | ||
|
||
bool isEmpty(Stack* stack) { | ||
return stack->top == -1; | ||
} | ||
|
||
void dfs(int node, bool visited[], int adj[][MAX], int n, Stack* stack) { | ||
visited[node] = true; | ||
for (int i = 0; i < n; i++) { | ||
if (adj[node][i] && !visited[i]) { | ||
dfs(i, visited, adj, n, stack); | ||
} | ||
} | ||
push(stack, node); | ||
} | ||
|
||
void dfsTranspose(int node, bool visited[], int transpose[][MAX], int n) { | ||
visited[node] = true; | ||
printf("%d ", node); | ||
for (int i = 0; i < n; i++) { | ||
if (transpose[node][i] && !visited[i]) { | ||
dfsTranspose(i, visited, transpose, n); | ||
} | ||
} | ||
} | ||
|
||
void kosaraju(int adj[][MAX], int n) { | ||
Stack stack; | ||
initStack(&stack); | ||
bool visited[MAX] = { false }; | ||
for (int i = 0; i < n; i++) { | ||
if (!visited[i]) { | ||
dfs(i, visited, adj, n, &stack); | ||
} | ||
} | ||
int transpose[MAX][MAX] = { 0 }; | ||
for (int i = 0; i < n; i++) { | ||
for (int j = 0; j < n; j++) { | ||
transpose[j][i] = adj[i][j]; | ||
} | ||
} | ||
for (int i = 0; i < n; i++) visited[i] = false; | ||
printf("Strongly Connected Components:\n"); | ||
while (!isEmpty(&stack)) { | ||
int node = pop(&stack); | ||
if (!visited[node]) { | ||
dfsTranspose(node, visited, transpose, n); | ||
printf("\n"); | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
int n, e; | ||
printf("Enter the number of vertices: "); | ||
scanf("%d", &n); | ||
printf("Enter the number of edges: "); | ||
scanf("%d", &e); | ||
int adj[MAX][MAX] = { 0 }; | ||
printf("Enter the edges (u v):\n"); | ||
for (int i = 0; i < e; i++) { | ||
int u, v; | ||
scanf("%d %d", &u, &v); | ||
adj[u][v] = 1; | ||
} | ||
kosaraju(adj, n); | ||
return 0; | ||
} |
109 changes: 109 additions & 0 deletions
109
DSA SOLUTIONS (TILL TREE & BASIC GRAPH CONCEPTS)/QUEUE/QueueImplement.C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include <iostream> | ||
using namespace std; | ||
|
||
#define MAX 1000 // Maximum size of the queue | ||
|
||
class Queue { | ||
private: | ||
int front, rear, size; | ||
int arr[MAX]; // Queue array | ||
|
||
public: | ||
// Constructor to initialize the queue | ||
Queue() { | ||
front = 0; | ||
rear = -1; | ||
size = 0; | ||
} | ||
|
||
// Function to check if the queue is empty | ||
bool isEmpty() { | ||
return size == 0; | ||
} | ||
|
||
// Function to check if the queue is full | ||
bool isFull() { | ||
return size == MAX; | ||
} | ||
|
||
// Function to add an element to the queue | ||
bool enqueue(int value) { | ||
if (isFull()) { | ||
cout << "Queue Overflow\n"; | ||
return false; | ||
} | ||
rear = (rear + 1) % MAX; // Circular increment | ||
arr[rear] = value; | ||
size++; | ||
return true; | ||
} | ||
|
||
// Function to remove an element from the queue | ||
int dequeue() { | ||
if (isEmpty()) { | ||
cout << "Queue Underflow\n"; | ||
return -1; | ||
} | ||
int value = arr[front]; | ||
front = (front + 1) % MAX; // Circular increment | ||
size--; | ||
return value; | ||
} | ||
|
||
// Function to get the front element of the queue | ||
int getFront() { | ||
if (isEmpty()) { | ||
cout << "Queue is Empty\n"; | ||
return -1; | ||
} | ||
return arr[front]; | ||
} | ||
|
||
// Function to get the rear element of the queue | ||
int getRear() { | ||
if (isEmpty()) { | ||
cout << "Queue is Empty\n"; | ||
return -1; | ||
} | ||
return arr[rear]; | ||
} | ||
|
||
// Function to display all elements in the queue | ||
void display() { | ||
if (isEmpty()) { | ||
cout << "Queue is Empty\n"; | ||
return; | ||
} | ||
cout << "Queue elements are: "; | ||
for (int i = 0; i < size; i++) { | ||
cout << arr[(front + i) % MAX] << " "; | ||
} | ||
cout << endl; | ||
} | ||
}; | ||
|
||
int main() { | ||
Queue q; | ||
|
||
// Demonstrating queue operations | ||
q.enqueue(10); | ||
q.enqueue(20); | ||
q.enqueue(30); | ||
|
||
cout << "Front element is: " << q.getFront() << endl; | ||
cout << "Rear element is: " << q.getRear() << endl; | ||
|
||
q.display(); | ||
|
||
cout << "Dequeued element: " << q.dequeue() << endl; | ||
|
||
q.display(); | ||
|
||
if (q.isEmpty()) { | ||
cout << "Queue is empty\n"; | ||
} else { | ||
cout << "Queue is not empty\n"; | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.