Sprint 2 - Algorithmic Efficiency Lesson (Javascript)
Lesson for the Algorithmic Effiency in Javascript
- ⚡ Algorithmic Efficiency in JavaScript
- ⏱ Runtime Complexity (Time)
- .sort() → O(n log n) because it divides and merges.
- Nested loops → O(n²) because it checks every pair.
- 🧩 Mini Activity 1
- 🔹 Common Operations & Their Complexities
- 🧩 Memory Complexity Overview
- 🧩 Summary
- Interactive Demo for Javascript
- JavaScript Algorithm Efficiency Demo
- 1️⃣ Find Max in Array
- 2️⃣ Filter Numbers Greater than N/2
- 3️⃣ Nested Loop Example
- 🧠 Runtime & Memory Complexity Quiz (Python + JavaScript)
⚡ Algorithmic Efficiency in JavaScript
In this lesson, we'll learn about:
- Runtime complexity (time)
- Memory complexity (space)
- How common operations affect efficiency
- Mini exercises to practice analysis
⏱ Runtime Complexity (Time)
Runtime complexity describes how the execution time of an algorithm scales with input size n.
Common complexities:
- O(1) — constant time
- O(log n) — logarithmic
- O(n) — linear
- O(n²) — quadratic
We’ll see examples next.
// O(1) - constant time complexity example
let nums = new Set([1,2,3,4]);
console.log(nums.has(3)); // O(1)
console.log(nums.has(5)); // O(1)
// O(n) — linear time
function sumArray(arr) {
let sum = 0;
for (let num of arr) sum += num;
return sum;
}
console.log(sumArray([1,2,3,4])); // 10
// O(n) — linear time
function sumArray(arr) {
let sum = 0;
for (let num of arr) sum += num;
return sum;
}
console.log(sumArray([1,2,3,4])); // 10
const arr1 = [5, 3, 8, 4, 2];
console.time("O(n log n)");
arr1.sort((a, b) => a - b);
console.timeEnd("O(n log n)");
const arr2 = [5, 3, 8, 4, 2];
console.time("O(n²)");
for (let i = 0; i < arr2.length; i++) {
for (let j = 0; j < arr2.length; j++) {
// simple comparison
if (arr2[i] > arr2[j]) {}
}
}
console.timeEnd("O(n²)");
.sort() → O(n log n) because it divides and merges.
Nested loops → O(n²) because it checks every pair.
🧩 Mini Activity 1
Predict the time and memory complexity of the following function:
function squareNumbers(n) {
let squares = [];
for (let i = 0; i < n; i++) {
squares.push(i * i);
}
return squares;
}
🔹 Common Operations & Their Complexities
| Operation | Array | Object | Set |
|---|---|---|---|
| Access | O(1) | O(1) | O(1) |
| Search | O(n) | O(1) | O(1) |
| Insert | O(1) end | O(1) | O(1) |
| Delete | O(n) middle | O(1) | O(1) |
| Memory | O(n) | O(n) | O(n) |
// Example: Using Set for efficient lookup
let nums = new Set([1,2,3,4]);
console.log(nums.has(3)); // O(1)
console.log(nums.has(5)); // O(1)
🧩 Memory Complexity Overview
Memory complexity measures how much memory an algorithm uses
relative to its input size n.
Common notations: O(1), O(n), O(n²), etc.
// 🧍 O(1) — Constant Space
function getFirst(arr) {
return arr[0]; // Uses fixed memory, no matter array size
}
console.log(getFirst([10, 20, 30]));
// Memory complexity: O(1)
// Explanation: The function uses a constant amount of memory regardless of the input size.
// 📦 O(n) — Linear Space
function copyArray(arr) {
let copy = [...arr]; // Creates a new array of same size
return copy;
}
console.log(copyArray([1, 2, 3, 4, 5]));
// Memory complexity: O(n)
// 🧮 O(n^2) — Quadratic Space
function buildMatrix(n) {
let matrix = [];
for (let i = 0; i < n; i++) {
matrix.push(new Array(n).fill(0));
}
return matrix;
}
console.log(buildMatrix(3));
// Memory complexity: O(n^2)
🧩 Summary
O(1): fixed memory (e.g., single variables)
O(n): memory grows linearly with input
O(n²): memory grows quadratically (e.g., matrices)
Goal: minimize space while maintaining performance
Memory complexity helps predict space growth with input size.