Skip to content

Commit febec02

Browse files
Merge branch 'main' into tree
2 parents b300ab9 + 975fdf6 commit febec02

File tree

11 files changed

+514
-0
lines changed

11 files changed

+514
-0
lines changed

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
dist
3+
.git
4+
.gitignore
5+
README.md

Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM node:22-alpine
2+
3+
WORKDIR /app
4+
COPY package*.json ./
5+
RUN npm install
6+
COPY . .
7+
EXPOSE 5173
8+
CMD ["npm", "run", "dev"]

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,31 @@ Understand searching logic through dynamic comparisons.
4444

4545
---
4646

47+
#### 🔹 Sliding Window Algorithms
48+
Demonstrate how the sliding window technique optimizes time complexity in problems involving subarrays and substrings.
49+
50+
**Algorithms Included:**
51+
- Maximum Sum of Subarray of Size K
52+
53+
**Interactive Options:**
54+
- Adjust window size
55+
- Control animation speed
56+
- Real-time window movement visualization
57+
- Dynamic highlighting of elements within the window
58+
- Step-by-step explanation of window expansion and contraction
59+
60+
**Algorithm Overview:**
61+
The Sliding Window technique maintains a subset of elements using two pointers (start, end) that "slide" over the array or string to efficiently compute results without redundant recalculations.
62+
63+
**General Approach:**
64+
1. Initialize start and end pointers
65+
2. Expand the window by moving end
66+
3. Process or evaluate current window state
67+
4. Shrink the window from start when constraints are violated
68+
5. Update the result as needed during traversal
69+
70+
---
71+
4772
#### 🔹 Pathfinding Algorithms (Graph / 2D Grid)
4873
Visualize how algorithms explore and find paths across a grid.
4974

@@ -162,7 +187,17 @@ Step through **state transitions** and **table updates** interactively to unders
162187
git clone https://github.com/<your-username>/Algo-Visualizer.git
163188
cd Algo-Visualizer
164189
```
190+
## 🐳 Run with Docker
191+
192+
Make sure **Docker** is installed and running on your system.
193+
You don’t need to install **Node.js** or any dependencies manually — Docker handles everything.
165194

195+
To start the development server, run:
196+
197+
```bash
198+
docker compose up
199+
```
200+
Then open http://localhost:5173 in your browser to view the app.
166201
### 2️⃣ Install Dependencies
167202
```bash
168203
npm install
@@ -186,12 +221,19 @@ Algo-Visualizer/
186221
│ ├── algorithms/
187222
│ │ ├── sorting/
188223
│ │ ├── searching/
224+
│ │ ├── sliding-window/
189225
│ │ ├── pathfinding/
190226
│ │ ├── graph/
191227
│ ├── components/
228+
│ │ ├── sorting/
229+
│ │ ├── searching/
230+
│ │ ├── sliding-window/
231+
│ │ ├── pathfinding/
232+
│ │ ├── graph/
192233
│ ├── pages/
193234
│ │ ├── sorting/
194235
│ │ ├── searching/
236+
│ │ ├── sliding-window/
195237
│ │ ├── pathfinding/
196238
│ │ ├── graph/
197239
│ ├── utils/

docker-compose.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
algo-visualizer:
3+
build: .
4+
container_name: algo-visualizer-dev
5+
ports:
6+
- "5173:5173"
7+
volumes:
8+
- .:/app
9+
- /app/node_modules
10+
command: ["npm", "run", "dev", "--", "--host"]

public/Sliding-Window.png

19.8 KB
Loading

src/App.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import DynamicProgrammingPage from "./pages/dynamic-programming/DyanmicProgrammi
99
import Searchingpage from "./pages/searching/searchingPage";
1010
import RecursionPage from "./pages/Recursion/RecursionPage";
1111
import Treepage from "./pages/Tree/Treepage";
12+
import SlidingWindowPage from "./pages/sliding-window/SlidingWindowPage";
1213
function App() {
1314
return (
1415
<Router>
@@ -22,6 +23,7 @@ function App() {
2223
<Route path="/dynamic-programming" element={<DynamicProgrammingPage />} />
2324
<Route path="/recursion" element={<RecursionPage/>}/>
2425
<Route path="/tree" element={<Treepage />} />
26+
<Route path="/sliding-window" element={<SlidingWindowPage/>}/>
2527
</Routes>
2628
</Router>
2729
);
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
export function* maxSumSubarray(array, k) {
2+
if (array.length === 0) {
3+
yield {
4+
type: "error",
5+
message: "Array cannot be empty",
6+
windowStart: -1, windowEnd: -1, currentSum: 0, maxSum: 0
7+
};
8+
return;
9+
}
10+
if (k > array.length) {
11+
yield {
12+
type: "error",
13+
message: `Window size ${k} cannot be greater than array length ${array.length}`,
14+
windowStart: -1, windowEnd: -1, currentSum: 0, maxSum: 0
15+
};
16+
return;
17+
}
18+
if (k <= 0) {
19+
yield {
20+
type: "error",
21+
message: "Window size must be greater than 0",
22+
windowStart: -1, windowEnd: -1, currentSum: 0, maxSum: 0
23+
};
24+
return;
25+
}
26+
let windowStart = 0;
27+
let windowEnd = 0;
28+
let currentSum = 0;
29+
let maxSum = Number.NEGATIVE_INFINITY;
30+
yield {
31+
type: "initialize",
32+
message: `Initializing: Calculating sum of first window [0, ${k - 1}]`,
33+
windowStart: 0,windowEnd: k - 1,currentSum: 0,maxSum: 0
34+
};
35+
for (let i = 0; i < k; i++) {
36+
currentSum += array[i];
37+
yield {
38+
type: "expand",
39+
message: `Adding element at index ${i}: ${array[i]}. Current sum: ${currentSum}`,
40+
windowStart: 0,windowEnd: i,currentSum: currentSum,maxSum: maxSum
41+
};
42+
}
43+
maxSum = currentSum;
44+
windowEnd = k - 1;
45+
46+
yield {
47+
type: "window_ready",
48+
message: `First window sum: ${currentSum}. This is our initial maximum.`,
49+
windowStart: 0, windowEnd: k - 1, currentSum: currentSum, maxSum: maxSum
50+
};
51+
for (let i = k; i < array.length; i++) {
52+
const removedElement = array[i - k];
53+
const addedElement = array[i];
54+
yield {
55+
type: "slide_start",
56+
message: `Sliding window: Removing element at index ${i - k} (${removedElement}), adding element at index ${i} (${addedElement})`,
57+
windowStart: i - k, windowEnd: i - 1, currentSum: currentSum, maxSum: maxSum, removedIndex: i - k, addedIndex: i
58+
};
59+
currentSum = currentSum - removedElement + addedElement;
60+
windowStart = i - k + 1;
61+
windowEnd = i;
62+
yield {
63+
type: "slide_update",
64+
message: `Window moved: New sum = ${currentSum} (previous: ${currentSum + removedElement - addedElement}, removed: ${removedElement}, added: ${addedElement})`,
65+
windowStart: windowStart, windowEnd: windowEnd, currentSum: currentSum, maxSum: maxSum, removedIndex: i - k, addedIndex: i
66+
};
67+
if (currentSum > maxSum) {
68+
maxSum = currentSum;
69+
yield {
70+
type: "new_max",
71+
message: `New maximum found! Sum: ${maxSum} at window [${windowStart}, ${windowEnd}]`,
72+
windowStart: windowStart, windowEnd: windowEnd, currentSum: currentSum, maxSum: maxSum
73+
};
74+
} else {
75+
yield {
76+
type: "window_ready",
77+
message: `Current sum: ${currentSum} (not greater than max: ${maxSum})`,
78+
windowStart: windowStart, windowEnd: windowEnd, currentSum: currentSum, maxSum: maxSum
79+
};
80+
}
81+
}
82+
yield {
83+
type: "done",
84+
message: `Algorithm completed! Maximum sum of subarray of size ${k} is ${maxSum}`,
85+
windowStart: windowStart, windowEnd: windowEnd, currentSum: currentSum, maxSum: maxSum
86+
};
87+
}
88+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from "react";
2+
3+
export default function MaxSumSubarrayVisualizer({array, windowStart, windowEnd, currentSum, maxSum, type, removedIndex, addedIndex}) {
4+
if (!array || array.length === 0) {
5+
return (
6+
<div className="flex items-center justify-center p-8 text-gray-400 text-lg">
7+
No array data to visualize
8+
</div>
9+
);
10+
}
11+
const maxValue = Math.max(...array, 1);
12+
const containerHeight = 320;
13+
14+
const getColor = (idx) => {
15+
if (windowStart < 0 || windowEnd < 0) return "bg-gray-600";
16+
if (type === "slide_start" && idx === removedIndex) return "bg-red-500";
17+
if ((type === "slide_start" || type === "slide_update") && idx === addedIndex)
18+
return "bg-yellow-400";
19+
if (type === "new_max" && idx >= windowStart && idx <= windowEnd)
20+
return "bg-purple-500 animate-pulse";
21+
if (idx === windowStart || idx === windowEnd) return "bg-green-500";
22+
if (idx >= windowStart && idx <= windowEnd) return "bg-blue-500";
23+
return "bg-gray-500";
24+
};
25+
26+
return (
27+
<div className="flex flex-col items-center">
28+
<div className="flex items-end justify-center space-x-4 transition-all duration-500">
29+
{array.map((value, idx) => {
30+
const color = getColor(idx);
31+
const height = Math.max((value / maxValue) * containerHeight, 40);
32+
return (
33+
<div key={idx} className="flex flex-col items-center">
34+
<div
35+
className={`${color} w-16 sm:w-12 rounded-t-md transition-all duration-300 shadow-lg`}
36+
style={{ height: `${height}px` }}
37+
></div>
38+
<span className="text-sm text-gray-200 mt-2 font-medium">
39+
{value}
40+
</span>
41+
</div>
42+
);
43+
})}
44+
</div>
45+
{windowStart >= 0 && windowEnd >= 0 && (
46+
<div className="flex justify-center gap-10 text-base text-gray-200 bg-gray-900/70 border border-gray-700 px-8 py-4 rounded-xl shadow-md">
47+
<div>
48+
<span className="text-gray-400">Window:</span>{" "}
49+
<span className="text-indigo-400 font-semibold text-lg">
50+
[{windowStart}, {windowEnd}]
51+
</span>
52+
</div>
53+
<div>
54+
<span className="text-gray-400">Sum:</span>{" "}
55+
<span className="text-yellow-400 font-semibold text-lg">
56+
{currentSum}
57+
</span>
58+
</div>
59+
<div>
60+
<span className="text-gray-400">Max:</span>{" "}
61+
<span className="text-purple-400 font-semibold text-lg">
62+
{maxSum !== Number.NEGATIVE_INFINITY ? maxSum : "N/A"}
63+
</span>
64+
</div>
65+
</div>
66+
)}
67+
</div>
68+
);
69+
}

src/pages/Homepage.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ const sections = [
2323
link: "/searching",
2424
flag: false
2525
},
26+
{
27+
title: "Sliding Window Algorithms",
28+
description:
29+
"Visualize how the sliding window technique efficiently processes subarrays and substrings with dynamic window movement.",
30+
phase: "Phase 1 (MVP)",
31+
img: "/Sliding-Window.png",
32+
link: "/sliding-window",
33+
flag: false
34+
},
2635
{
2736
title: "Pathfinding Algorithms",
2837
description:

0 commit comments

Comments
 (0)