MUST SEE JS CODING CHALLENGES - rs-hash/GETTHATJOB GitHub Wiki

βœ… 1. Easy β€” Two Sum
  • Idea: Hash map of complements for O(n).
  • Complexity: O(n) time, O(n) space.
Solution

🧩 Two Sum β€” JavaScript (Brute Force β†’ Optimal Hash Map)

Problem:
Given an array of integers nums and an integer target, return the indices of the two numbers such that they add up to the target.
You may assume that each input has exactly one solution, and you may not use the same element twice.


πŸ“˜ Summary

Approach Time Space Notes
🐒 Brute Force O(n²) O(1) Simple but slow
⚑ Hash Map (Optimal) βœ… O(n) O(n) Best solution

🧠 Step 1: Brute Force β€” O(nΒ²)

πŸ’‘ Idea

Compare every pair (i, j) and return when nums[i] + nums[j] === target.

function twoSumBrute(nums, target) {
  for (let i = 0; i < nums.length; i++) {
    for (let j = i + 1; j < nums.length; j++) {
      if (nums[i] + nums[j] === target) {
        return [i, j];
      }
    }
  }
}

🧾 Example

twoSumBrute([1, 4, 6, 8], 10);
// Pair (4,6) β†’ indices [1,2]

⏱️ Complexity

  • Time: O(nΒ²)
  • Space: O(1)

⚑ Step 2: Optimal Solution β€” Hash Map (O(n))

πŸ’‘ Idea

For each number, check if its complement (target - num) exists in a hash map.
If it does, return both indices; if not, store the number in the map.

function twoSum(nums, target) {
  const map = new Map(); // number β†’ index
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    if (map.has(complement)) {
      return [map.get(complement), i];
    }
    map.set(nums[i], i);
  }
}

🧩 Dry Run Example

const nums = [5, 1, 7, 2, 9];
const target = 8;
i nums[i] complement map (before) Found? Action
0 5 3 {} ❌ Add (5 β†’ 0)
1 1 7 {5:0} ❌ Add (1 β†’ 1)
2 7 1 {5:0,1:1} βœ… Found complement 1 β†’ return [1,2]

βœ… Output β†’ [1, 2]
(nums[1] + nums[2] = 1 + 7 = 8)


βœ… Complexity

Metric Complexity
Time O(n)
Space O(n)
Reasoning Single-pass with constant-time lookups

πŸ§ͺ Test Cases

console.log(twoSum([2, 7, 11, 15], 9));   // [0, 1]
console.log(twoSum([3, 2, 4], 6));        // [1, 2]
console.log(twoSum([3, 3], 6));           // [0, 1]
console.log(twoSum([5, 1, 7, 2, 9], 8));  // [1, 2]

🧠 Senior Dev Insight

β€œI started with a brute-force baseline for correctness, then optimized using a hash map for O(n) time.
This same patternβ€”using a lookup table to avoid nested loopsβ€”is common in front-end performance work,
like caching computed layouts, memoizing API results, or optimizing React state updates.”


🏁 Final Takeaway

When to Use Approach
Small arrays or prototypes Brute Force
Real apps, interviews, or large data βœ… Hash Map (O(n))
βœ… 2. Easy β€” Valid Parentheses
  1. Idea: Stack, push opens, match closes.
  2. Complexity: O(n) time, O(n) space.
Solution
function isValid(s) {
  const pairs = {')':'(', ']':'[', '}':'{'};
  const st = [];
  for (const ch of s) {
    if (pairs[ch]) {
      if (st.pop() !== pairs[ch]) return false;
    } else st.push(ch);
  }
  return st.length === 0;
}
βœ… Easy β€” Merge Two Sorted Arrays (in-place assuming one has space)
  1. Idea: Two-pointer from end for in-place merge.
  2. Complexity: O(m+n) time, O(1) extra space.
Solution
// merge nums2 into nums1, where nums1 has m valid elements and space for n more
function merge(nums1, m, nums2, n) {
  let i = m - 1, j = n - 1, k = m + n - 1;
  while (j >= 0) {
    if (i >= 0 && nums1[i] > nums2[j]) nums1[k--] = nums1[i--];
    else nums1[k--] = nums2[j--];
  }
}
βœ… Easy β€” Move Zeroes to End
  1. Idea: Two-pointer swap/overwrite non-zero values.
  2. Complexity: O(n) time, O(1) space.
Solution
function moveZeroes(nums) {
  let lastNonZero = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] !== 0) {
      if (i !== lastNonZero) {
        [nums[lastNonZero], nums[i]] = [nums[i], nums[lastNonZero]];
      }
      lastNonZero++;
    }
  }
}
βœ… Easy β€” Find Missing Number in Array
  1. Idea: XOR or sum formula. XOR avoids overflow.
  2. Complexity: O(n) time, O(1) space.
Solution
function missingNumber(nums) {
  let xor = 0;
  const n = nums.length;
  for (let i = 0; i < n; i++) {
    xor ^= nums[i] ^ (i + 1);
  }
  return xor;
}
βœ… Easy β€” Count Unique Values (sorted array)
  1. Idea: Two pointers in-place count.
  2. Complexity: O(n) time, O(1) space.
Solution
function countUnique(arr) {
  if (!arr.length) return 0;
  let i = 0;
  for (let j = 1; j < arr.length; j++) {
    if (arr[i] !== arr[j]) arr[++i] = arr[j];
  }
  return i + 1;
}
βœ… Easy β€” Reverse a Linked List
  • Idea: Iterative rewire pointers.
  • Complexity: O(n) time, O(1) space.
Solution
function reverseList(head) {
  let prev = null, curr = head;
  while (curr) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
}
βœ… Easy β€” Palindrome Checker (string)
  • Idea: Two pointers, skip non-alphanumeric if required. Here plain check.
  • Complexity: O(n) time, O(1) space.
Solution
function isPalindrome(s) {
  let i = 0, j = s.length - 1;
  while (i < j) {
    while (i < j && !/[a-zA-Z0-9]/.test(s[i])) i++;
    while (i < j && !/[a-zA-Z0-9]/.test(s[j])) j--;
    if (s[i].toLowerCase() !== s[j].toLowerCase()) return false;
    i++; j--;
  }
  return true;
}
βœ… Easy β€” Max/Min in Array
  1. Idea: Single pass track max & min.
  2. Complexity: O(n) time, O(1) space.
Solution
function minMax(arr) {
  if (!arr.length) return null;
  let min = Infinity, max = -Infinity;
  for (const v of arr) {
    if (v < min) min = v;
    if (v > max) max = v;
  }
  return { min, max };
}
βœ… Easy β€” Climbing Stairs (DP)
  1. Idea: Fibonacci iterative DP.
  2. Complexity: O(n) time, O(1) space.
Solution
function climbStairs(n) {
  if (n <= 1) return 1;
  let a = 1, b = 1;
  for (let i = 2; i <= n; i++) {
    [a, b] = [b, a + b];
  }
  return b;
}
βœ… Easy β€” Intersection of Two Arrays
  1. Idea: Use set for unique intersection.
  2. Complexity: O(n+m) time, O(min(n,m)) space.
Solution
function intersection(a, b) {
  const setA = new Set(a), res = new Set();
  for (const x of b) if (setA.has(x)) res.add(x);
  return Array.from(res);
}
βœ… Easy β€” FizzBuzz
  1. Idea: Simple loop.
  2. Complexity: O(n) time, O(1) extra space.
Solution
function fizzBuzz(n) {
  const res = [];
  for (let i = 1; i <= n; i++) {
    if (i % 15 === 0) res.push("FizzBuzz");
    else if (i % 3 === 0) res.push("Fizz");
    else if (i % 5 === 0) res.push("Buzz");
    else res.push(String(i));
  }
  return res;
}
βœ… Easy β€” Merge Strings Alternately
  1. Idea: Two-pointer merge.
  2. Complexity: O(n+m) time, O(n+m) space.
Solution
function mergeAlternately(a, b) {
  let i = 0, j = 0, out = '';
  while (i < a.length || j < b.length) {
    if (i < a.length) out += a[i++];
    if (j < b.length) out += b[j++];
  }
  return out;
}
βœ… Easy β€” Maximum Subarray (Kadane’s)
  1. Idea: Kadane's algorithm.
  2. Complexity: O(n) time, O(1) space.
Solution
function maxSubArray(nums) {
  let maxSoFar = -Infinity, curr = 0;
  for (const n of nums) {
    curr = Math.max(n, curr + n);
    maxSoFar = Math.max(maxSoFar, curr);
  }
  return maxSoFar;
}
βœ… Easy β€” Remove Duplicates from Sorted Array
  1. Idea: Two-pointer in-place.
  2. Complexity: O(n) time, O(1) space.
Solution
function removeDuplicates(nums) {
  if (!nums.length) return 0;
  let i = 0;
  for (let j = 1; j < nums.length; j++) {
    if (nums[j] !== nums[i]) nums[++i] = nums[j];
  }
  return i + 1;
}
βš™οΈ Medium β€” Longest Substring Without Repeating Characters
  1. Idea: Sliding window with last-index map.
  2. Complexity: O(n) time, O(min(n, charset)) space.
Solution
function lengthOfLongestSubstring(s) {
  const last = new Map();
  let start = 0, maxLen = 0;
  for (let i = 0; i < s.length; i++) {
    if (last.has(s[i])) start = Math.max(start, last.get(s[i]) + 1);
    last.set(s[i], i);
    maxLen = Math.max(maxLen, i - start + 1);
  }
  return maxLen;
}
βš™οΈ Medium β€” Group Anagrams
  1. Idea: Use sorted key or frequency signature.
  2. Complexity: O(n * k log k) with sorting, or O(n * k) with freq key.
Solution (freq key)
function groupAnagrams(strs) {
  const map = new Map();
  for (const s of strs) {
    const freq = new Array(26).fill(0);
    for (const ch of s) freq[ch.charCodeAt(0) - 97]++;
    const key = freq.join('#');
    if (!map.has(key)) map.set(key, []);
    map.get(key).push(s);
  }
  return Array.from(map.values());
}
βš™οΈ Medium β€” Sliding Window Maximum
  1. Idea: Deque to keep indices of potential maxima.
  2. Complexity: O(n) time, O(k) space.
Solution
function maxSlidingWindow(nums, k) {
  const res = [], dq = []; // store indices, decreasing values
  for (let i = 0; i < nums.length; i++) {
    while (dq.length && dq[0] <= i - k) dq.shift();
    while (dq.length && nums[dq[dq.length - 1]] < nums[i]) dq.pop();
    dq.push(i);
    if (i >= k - 1) res.push(nums[dq[0]]);
  }
  return res;
}
βš™οΈ Medium β€” Flatten Nested Arrays (robust, iterative)
  1. Idea: Iterative stack to avoid deep recursion.
  2. Complexity: O(n) time, O(n) space.
Solution
function flatten(arr) {
  const stack = [...arr];
  const res = [];
  while (stack.length) {
    const val = stack.pop();
    if (Array.isArray(val)) {
      for (let i = val.length - 1; i >= 0; i--) stack.push(val[i]);
    } else res.push(val);
  }
  return res.reverse();
}

// Example:
// console.log(flatten([1,[2,[3,[4]]]])); // [1,2,3,4]
βš™οΈ Medium β€” Rotate Array (k steps)
  1. Idea: Reverse whole, reverse parts (in-place).
  2. Complexity: O(n) time, O(1) space.
Solution
function rotate(nums, k) {
  k %= nums.length;
  const rev = (i, j) => {
    while (i < j) [nums[i++], nums[j--]] = [nums[j], nums[i]];
  };
  rev(0, nums.length - 1);
  rev(0, k - 1);
  rev(k, nums.length - 1);
}
βš™οΈ Medium β€” Top K Frequent Elements
  1. Idea: Map frequencies + bucket sort or min-heap. Bucket sort O(n).
  2. Complexity: O(n) time avg, O(n) space.
Solution (bucket)
function topKFrequent(nums, k) {
  const freq = new Map();
  for (const n of nums) freq.set(n, (freq.get(n) || 0) + 1);
  const buckets = Array(nums.length + 1).fill(0).map(() => []);
  for (const [num, count] of freq) buckets[count].push(num);
  const res = [];
  for (let i = buckets.length - 1; i >= 0 && res.length < k; i--) {
    for (const val of buckets[i]) {
      res.push(val);
      if (res.length === k) break;
    }
  }
  return res;
}
βš™οΈ Medium β€” Merge Intervals
  1. Idea: Sort by start, merge sweep.
  2. Complexity: O(n log n) time, O(n) space.
Solution
function mergeIntervals(intervals) {
  if (!intervals.length) return [];
  intervals.sort((a, b) => a[0] - b[0]);
  const res = [intervals[0].slice()];
  for (let i = 1; i < intervals.length; i++) {
    const [s, e] = intervals[i];
    const last = res[res.length - 1];
    if (s <= last[1]) last[1] = Math.max(last[1], e);
    else res.push([s, e]);
  }
  return res;
}
βš™οΈ Medium β€” LRU Cache (class-based)
  1. Idea: Doubly linked list + map for O(1) operations.
  2. Complexity: O(1) get/put, O(capacity) space.
Solution
class Node {
  constructor(k, v) { this.k = k; this.v = v; this.prev = null; this.next = null; }
}
class LRUCache {
  constructor(capacity) {
    this.cap = capacity;
    this.map = new Map();
    this.head = new Node(0,0); // dummy head
    this.tail = new Node(0,0); // dummy tail
    this.head.next = this.tail;
    this.tail.prev = this.head;
  }
  _remove(node) {
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }
  _add(node) {
    node.next = this.head.next;
    node.prev = this.head;
    this.head.next.prev = node;
    this.head.next = node;
  }
  get(key) {
    if (!this.map.has(key)) return -1;
    const node = this.map.get(key);
    this._remove(node);
    this._add(node);
    return node.v;
  }
  put(key, value) {
    if (this.map.has(key)) {
      this._remove(this.map.get(key));
    }
    const node = new Node(key, value);
    this._add(node);
    this.map.set(key, node);
    if (this.map.size > this.cap) {
      const lru = this.tail.prev;
      this._remove(lru);
      this.map.delete(lru.k);
    }
  }
}
βš™οΈ Medium β€” Deep Clone Object

Idea: DFS with map to handle cycles and prototypes if desired. Complexity: O(n) time, O(n) space.

Solution
function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj);
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
  const copy = Array.isArray(obj) ? [] : Object.create(Object.getPrototypeOf(obj));
  map.set(obj, copy);
  for (const key of Reflect.ownKeys(obj)) {
    copy[key] = deepClone(obj[key], map);
  }
  return copy;
}
βš™οΈ Medium β€” Search in Rotated Sorted Array
  1. Idea: Modified binary search.
  2. Complexity: O(log n) time, O(1) space.
Solution
function search(nums, target) {
  let l = 0, r = nums.length - 1;
  while (l <= r) {
    const m = Math.floor((l + r) / 2);
    if (nums[m] === target) return m;
    if (nums[l] <= nums[m]) { // left sorted
      if (target >= nums[l] && target < nums[m]) r = m - 1;
      else l = m + 1;
    } else { // right sorted
      if (target > nums[m] && target <= nums[r]) l = m + 1;
      else r = m - 1;
    }
  }
  return -1;
}
βš™οΈ Medium β€” Decode String (e.g., "3[a2[c]]")

Idea: Stack decode counting and strings. Complexity: O(n) time, O(n) space.

Solution
function decodeString(s) {
  const counts = [], res = [], str = [];
  let currNum = 0, currStr = '';
  for (const ch of s) {
    if (/\d/.test(ch)) currNum = currNum * 10 + +ch;
    else if (ch === '[') {
      counts.push(currNum);
      res.push(currStr);
      currNum = 0;
      currStr = '';
    } else if (ch === ']') {
      const times = counts.pop();
      const prev = res.pop();
      currStr = prev + currStr.repeat(times);
    } else currStr += ch;
  }
  return currStr;
}
βš™οΈ Medium β€” Longest Palindromic Substring (expand center)
  1. Idea: Expand around centers for O(n^2) worst-case but simple; Manacher’s is O(n).
  2. Complexity: O(n^2) time, O(1) space (expand method).
Solution (center expand)
function longestPalindrome(s) {
  if (!s) return "";
  let start = 0, end = 0;
  const expand = (l, r) => {
    while (l >= 0 && r < s.length && s[l] === s[r]) { l--; r++; }
    return r - l - 1;
  };
  for (let i = 0; i < s.length; i++) {
    const len1 = expand(i, i);
    const len2 = expand(i, i + 1);
    const len = Math.max(len1, len2);
    if (len > end - start + 1) {
      start = i - Math.floor((len - 1) / 2);
      end = i + Math.floor(len / 2);
    }
  }
  return s.slice(start, end + 1);
}
βš™οΈ Medium β€” Word Break Problem
  1. Idea: DP with a set of words.
  2. Complexity: O(n^2) time, O(n) space.
Solution
function wordBreak(s, wordDict) {
  const n = s.length, dp = Array(n + 1).fill(false);
  const set = new Set(wordDict);
  dp[0] = true;
  for (let i = 1; i <= n; i++) {
    for (let j = 0; j < i; j++) {
      if (dp[j] && set.has(s.slice(j, i))) { dp[i] = true; break; }
    }
  }
  return dp[n];
}

</details> ``` </details> 

<details> <summary>βš™οΈ Medium β€” Subsets (Power Set)</summary>

> 1. Idea: Iterative or backtracking.
> 1. Complexity: O(2^n * n) time, O(2^n * n) space.

<details>
<summary>Solution (iterative)</summary>

```js
function subsets(nums) {
  const res = [[]];
  for (const n of nums) {
    const size = res.length;
    for (let i = 0; i < size; i++) res.push([...res[i], n]);
  }
  return res;
}
βš™οΈ Medium β€” Binary Search on Answer (e.g., Koko Eating Bananas)
  1. Idea: Binary search over possible answer space + feasibility check.
  2. Complexity: O(n log R) where R is search range.
Pattern Example
function minEatingSpeed(piles, h) {
  const can = (k) => {
    let hours = 0;
    for (const p of piles) hours += Math.ceil(p / k);
    return hours <= h;
  };
  let l = 1, r = Math.max(...piles);
  while (l < r) {
    const mid = Math.floor((l + r) / 2);
    if (can(mid)) r = mid;
    else l = mid + 1;
  }
  return l;
}
πŸ”₯ Hard β€” Median of Two Sorted Arrays
  1. Idea: Binary search on the smaller array to partition.
  2. Complexity: O(log(min(m,n))) time, O(1) space.
Solution
function findMedianSortedArrays(a, b) {
  if (a.length > b.length) [a, b] = [b, a];
  const m = a.length, n = b.length;
  let low = 0, high = m;
  while (low <= high) {
    const i = Math.floor((low + high) / 2);
    const j = Math.floor((m + n + 1) / 2) - i;
    const aLeft = i === 0 ? -Infinity : a[i - 1];
    const aRight = i === m ? Infinity : a[i];
    const bLeft = j === 0 ? -Infinity : b[j - 1];
    const bRight = j === n ? Infinity : b[j];
    if (aLeft <= bRight && bLeft <= aRight) {
      if ((m + n) % 2 === 0) return (Math.max(aLeft, bLeft) + Math.min(aRight, bRight)) / 2;
      return Math.max(aLeft, bLeft);
    } else if (aLeft > bRight) high = i - 1;
    else low = i + 1;
  }
  return null;
}
πŸ”₯ Hard β€” Detect & Remove Cycle in Linked List
  1. Idea: Floyd’s cycle detection; remove by finding cycle start.
  2. Complexity: O(n) time, O(1) space.
Solution
function detectCycle(head) {
  let slow = head, fast = head;
  while (fast && fast.next) {
    slow = slow.next; fast = fast.next.next;
    if (slow === fast) {
      slow = head;
      while (slow !== fast) { slow = slow.next; fast = fast.next; }
      return slow;
    }
  }
  return null;
}

// To remove cycle:
function removeCycle(head) {
  const start = detectCycle(head);
  if (!start) return head;
  let ptr = start;
  while (ptr.next !== start) ptr = ptr.next;
  ptr.next = null;
  return head;
}
πŸ”₯ Hard β€” Merge K Sorted Lists
  1. Idea: Min-heap (priority queue) merging.
  2. Complexity: O(N log k) time where N total nodes, k lists.
Solution (using simple heap)
class MinHeap {
  constructor() { this.a = []; }
  _cmp(i, j) { return this.a[i].val - this.a[j].val; }
  push(node) {
    this.a.push(node);
    let i = this.a.length - 1;
    while (i > 0) {
      const p = Math.floor((i - 1) / 2);
      if (this._cmp(i, p) >= 0) break;
      [this.a[i], this.a[p]] = [this.a[p], this.a[i]];
      i = p;
    }
  }
  pop() {
    if (!this.a.length) return null;
    const top = this.a[0];
    const last = this.a.pop();
    if (this.a.length) {
      this.a[0] = last;
      let i = 0;
      while (true) {
        let l = 2 * i + 1, r = 2 * i + 2, smallest = i;
        if (l < this.a.length && this._cmp(l, smallest) < 0) smallest = l;
        if (r < this.a.length && this._cmp(r, smallest) < 0) smallest = r;
        if (smallest === i) break;
        [this.a[i], this.a[smallest]] = [this.a[smallest], this.a[i]];
        i = smallest;
      }
    }
    return top;
  }
  size() { return this.a.length; }
}

function mergeKLists(lists) {
  const heap = new MinHeap();
  for (const l of lists) if (l) heap.push(l);
  const dummy = { next: null }, tail = dummy;
  let curTail = dummy;
  while (heap.size()) {
    const node = heap.pop();
    curTail.next = node;
    curTail = curTail.next;
    if (node.next) heap.push(node.next);
  }
  curTail.next = null;
  return dummy.next;
}
πŸ”₯ Hard β€” Serialize/Deserialize Tree (binary)
  1. Idea: Preorder with null markers, or level-order.
  2. Complexity: O(n) time, O(n) space.
Solution (preorder)
function serialize(root) {
  const res = [];
  (function dfs(node) {
    if (!node) { res.push('#'); return; }
    res.push(String(node.val));
    dfs(node.left);
    dfs(node.right);
  })(root);
  return res.join(',');
}

function deserialize(data) {
  const arr = data.split(',');
  let i = 0;
  function dfs() {
    if (arr[i] === '#') { i++; return null; }
    const node = { val: Number(arr[i++]), left: null, right: null };
    node.left = dfs();
    node.right = dfs();
    return node;
  }
  return dfs();
}
πŸ”₯ Hard β€” Trapping Rain Water
  1. Idea: Two-pointer from both ends.
  2. Complexity: O(n) time, O(1) space.
Solution
function trap(height) {
  let l = 0, r = height.length - 1, leftMax = 0, rightMax = 0, ans = 0;
  while (l <= r) {
    if (height[l] <= height[r]) {
      leftMax = Math.max(leftMax, height[l]);
      ans += leftMax - height[l];
      l++;
    } else {
      rightMax = Math.max(rightMax, height[r]);
      ans += rightMax - height[r];
      r--;
    }
  }
  return ans;
}
πŸ”₯ Hard β€” Maximum Product Subarray
  1. Idea: Track max and min products due to negatives.
  2. Complexity: O(n) time, O(1) space.
Solution
function maxProduct(nums) {
  let maxSoFar = nums[0], minSoFar = nums[0], ans = nums[0];
  for (let i = 1; i < nums.length; i++) {
    const a = nums[i];
    if (a < 0) [maxSoFar, minSoFar] = [minSoFar, maxSoFar];
    maxSoFar = Math.max(a, maxSoFar * a);
    minSoFar = Math.min(a, minSoFar * a);
    ans = Math.max(ans, maxSoFar);
  }
  return ans;
}
πŸ”₯ Hard β€” Implement Priority Queue
  1. Idea: Binary heap wrapper.
  2. Complexity: O(log n) push/pop.
Solution
class PriorityQueue {
  constructor(comparator = (a,b) => a - b) {
    this.a = []; this.c = comparator;
  }
  size() { return this.a.length; }
  peek() { return this.a[0] ?? null; }
  push(val) {
    this.a.push(val);
    let i = this.a.length - 1;
    while (i > 0) {
      const p = (i - 1) >> 1;
      if (this.c(this.a[i], this.a[p]) >= 0) break;
      [this.a[i], this.a[p]] = [this.a[p], this.a[i]];
      i = p;
    }
  }
  pop() {
    if (!this.a.length) return null;
    const top = this.a[0];
    const last = this.a.pop();
    if (this.a.length) {
      this.a[0] = last;
      let i = 0;
      while (true) {
        let l = 2*i+1, r = 2*i+2, best = i;
        if (l < this.a.length && this.c(this.a[l], this.a[best]) < 0) best = l;
        if (r < this.a.length && this.c(this.a[r], this.a[best]) < 0) best = r;
        if (best === i) break;
        [this.a[i], this.a[best]] = [this.a[best], this.a[i]];
        i = best;
      }
    }
    return top;
  }
}
πŸ”₯ Hard β€” Autocomplete System (Trie)
  1. Idea: Trie with insert and prefix search; store suggestions per node for speed.
  2. Complexity: Insert/search O(length) time.
Solution (basic)
class TrieNode {
  constructor() { this.children = {}; this.isEnd = false; this.words = []; }
}
class Autocomplete {
  constructor() { this.root = new TrieNode(); }
  insert(word) {
    let node = this.root;
    for (const ch of word) {
      if (!node.children[ch]) node.children[ch] = new TrieNode();
      node = node.children[ch];
      // optionally maintain top-k suggestions by frequency
    }
    node.isEnd = true;
  }
  find(prefix) {
    let node = this.root;
    for (const ch of prefix) {
      if (!node.children[ch]) return [];
      node = node.children[ch];
    }
    const res = [];
    (function dfs(n, path) {
      if (res.length >= 10) return; // limit
      if (n.isEnd) res.push(path);
      for (const c in n.children) dfs(n.children[c], path + c);
    })(node, prefix);
    return res;
  }
}
πŸ”₯ Hard β€” LRU Cache (class-based) β€” already provided above

(See the Medium LRU Cache entry for a polished class-based implementation.)

πŸ”₯ Hard β€” N-Queens
  1. Idea: Backtracking with pruning via columns and diagonals sets.
  2. Complexity: Exponential worst-case; optimized pruning.
Solution
function solveNQueens(n) {
  const cols = new Set(), diag1 = new Set(), diag2 = new Set(), board = Array(n).fill().map(() => Array(n).fill('.'));
  const res = [];
  const dfs = (r) => {
    if (r === n) {
      res.push(board.map(row => row.join('')));
      return;
    }
    for (let c = 0; c < n; c++) {
      if (cols.has(c) || diag1.has(r - c) || diag2.has(r + c)) continue;
      cols.add(c); diag1.add(r - c); diag2.add(r + c);
      board[r][c] = 'Q';
      dfs(r + 1);
      board[r][c] = '.';
      cols.delete(c); diag1.delete(r - c); diag2.delete(r + c);
    }
  };
  dfs(0);
  return res;
}
πŸ”₯ Hard β€” Word Ladder
  1. Idea: BFS on word graph using wildcards precompute neighbors.
  2. Complexity: O(M * N) where M word length, N dictionary size.
Solution (beginWord -> endWord)
function ladderLength(beginWord, endWord, wordList) {
  const set = new Set(wordList);
  if (!set.has(endWord)) return 0;
  const allCombo = new Map();
  const L = beginWord.length;
  for (const word of set) {
    for (let i = 0; i < L; i++) {
      const key = word.slice(0, i) + '*' + word.slice(i+1);
      if (!allCombo.has(key)) allCombo.set(key, []);
      allCombo.get(key).push(word);
    }
  }
  const q = [[beginWord, 1]];
  const visited = new Set([beginWord]);
  while (q.length) {
    const [word, level] = q.shift();
    for (let i = 0; i < L; i++) {
      const key = word.slice(0, i) + '*' + word.slice(i+1);
      for (const adj of allCombo.get(key) || []) {
        if (adj === endWord) return level + 1;
        if (!visited.has(adj)) { visited.add(adj); q.push([adj, level + 1]); }
      }
    }
  }
  return 0;
}
πŸ”₯ Hard β€” Longest Consecutive Sequence
  1. Idea: Use set and only build from sequence starts.
  2. Complexity: O(n) time, O(n) space.
Solution
function longestConsecutive(nums) {
  const s = new Set(nums);
  let best = 0;
  for (const x of s) {
    if (!s.has(x - 1)) {
      let cur = x, len = 1;
      while (s.has(cur + 1)) { cur++; len++; }
      best = Math.max(best, len);
    }
  }
  return best;
}
πŸ”₯ Hard β€” Redundant Connection in Graph
  1. Idea: Union-Find to detect cycle edge.
  2. Complexity: Nearly O(n) with union-by-rank.
Solution
function findRedundantConnection(edges) {
  const n = edges.length;
  const parent = Array(n+1).fill(0).map((_, i) => i), rank = Array(n+1).fill(0);
  const find = (x) => (parent[x] === x ? x : parent[x] = find(parent[x]));
  const union = (a, b) => {
    a = find(a); b = find(b);
    if (a === b) return false;
    if (rank[a] < rank[b]) parent[a] = b;
    else if (rank[a] > rank[b]) parent[b] = a;
    else { parent[b] = a; rank[a]++; }
    return true;
  };
  for (const [u,v] of edges) {
    if (!union(u, v)) return [u, v];
  }
  return null;
}
πŸ”₯ Hard β€” Scheduler with Priorities (sketch)
  1. Idea: Priority queue based on next execution time and priority. Use heap keyed by (priority, nextTime).
  2. Complexity: depends on schedule ops β€” typically O(log n) per schedule.
Sketch
// Use PriorityQueue from above, keyed by {nextAt, priority, taskId, fn}
// pop tasks when currentTime >= nextAt
πŸ”₯ Hard β€” Build a Virtual DOM diff logic (sketch)
  1. Idea: Compare trees by type, props, children; apply minimal patches. Use keys to speed reorder detection.
  2. Complexity: O(n) typical with heuristics.
Sketch
// Outline:
// diff(oldNode, newNode):
//  - if types differ -> replace
//  - update props diffs
//  - diff children: keyed map approach for O(n)
// Apply patches list to real DOM.
πŸ§ͺ Miscellaneous β€” Debounce function
  1. Idea: Reset timer on each call. Optionally immediate.
  2. Complexity: O(1) per call.
Solution
function debounce(fn, wait, immediate = false) {
  let timer = null;
  return function(...args) {
    const ctx = this;
    const later = () => { timer = null; if (!immediate) fn.apply(ctx, args); };
    const callNow = immediate && !timer;
    clearTimeout(timer);
    timer = setTimeout(later, wait);
    if (callNow) fn.apply(ctx, args);
  };
}
πŸ§ͺ Miscellaneous β€” Throttle function
  1. Idea: Limit calls to once per interval; leading/trailing options.
  2. Complexity: O(1) per call.
Solution
function throttle(fn, wait) {
  let last = 0, timer = null;
  return function(...args) {
    const now = Date.now();
    if (now - last >= wait) {
      last = now;
      fn.apply(this, args);
    } else if (!timer) {
      timer = setTimeout(() => {
        last = Date.now();
        timer = null;
        fn.apply(this, args);
      }, wait - (now - last));
    }
  };
}
πŸ§ͺ Miscellaneous β€” Custom bind / call / apply
  1. Idea: Use function property assignment and Symbol to avoid collisions.
  2. Complexity: O(1) setup.
Solution
Function.prototype.myCall = function(ctx, ...args) {
  ctx = ctx ?? globalThis;
  const sym = Symbol();
  ctx[sym] = this;
  const res = ctx[sym](...args);
  delete ctx[sym];
  return res;
};

Function.prototype.myApply = function(ctx, args = []) {
  ctx = ctx ?? globalThis;
  const sym = Symbol();
  ctx[sym] = this;
  const res = ctx[sym](...args);
  delete ctx[sym];
  return res;
};

Function.prototype.myBind = function(ctx, ...bindArgs) {
  const fn = this;
  return function(...args) { return fn.apply(ctx, [...bindArgs, ...args]); };
};
πŸ§ͺ Miscellaneous β€” Memoization in JS
  1. Idea: Cache results by key (primitive or JSON serialized).
  2. Complexity: Depends on fn.
Solution
function memoize(fn, resolver = JSON.stringify) {
  const cache = new Map();
  return function(...args) {
    const key = resolver(args);
    if (cache.has(key)) return cache.get(key);
    const val = fn.apply(this, args);
    cache.set(key, val);
    return val;
  };
}
πŸ§ͺ Miscellaneous β€” useState / useReducer from scratch (hook-like)

Idea: Simple closures to mimic state container (not real React). Complexity: O(1).

Solution (basic)
function createSimpleRenderer() {
  let state = [];
  let idx = 0;
  return {
    reset() { idx = 0; },
    useState(init) {
      const i = idx;
      state[i] = state[i] ?? (typeof init === 'function' ? init() : init);
      const setState = (v) => { state[i] = typeof v === 'function' ? v(state[i]) : v; };
      idx++;
      return [state[i], setState];
    },
    useReducer(reducer, init) {
      const [s, setS] = this.useState(init);
      const dispatch = (action) => setS(prev => reducer(prev, action));
      return [s, dispatch];
    }
  };
}
πŸ§ͺ Miscellaneous β€” Deep vs Shallow Copy (explanation + example)
  1. Idea: shallow copy copies refs; deep clone recursively copies values (see deepClone above).
  2. Complexity: shallow O(n), deep O(n) with recursion/structures.
Example
const obj = { a: {b:1} };
const shallow = {...obj}; // shallow.a === obj.a
const deep = deepClone(obj); // deep.a !== obj.a
πŸ§ͺ Miscellaneous β€” Curry function

Idea: Return nested functions until enough args. Complexity: O(n) closure overhead.

Solution
function curry(fn, arity = fn.length) {
  return function curried(...args) {
    if (args.length >= arity) return fn(...args);
    return (...more) => curried(...args, ...more);
  };
}
πŸ§ͺ Miscellaneous β€” Flatten deeply nested object (keys)
  1. Idea: DFS produce dotted keys.
  2. Complexity: O(n) time & space.
Solution
function flattenObject(obj, prefix = '', res = {}) {
  for (const k in obj) {
    const val = obj[k];
    const key = prefix ? `${prefix}.${k}` : k;
    if (val && typeof val === 'object' && !Array.isArray(val)) flattenObject(val, key, res);
    else res[key] = val;
  }
  return res;
}
πŸ§ͺ Miscellaneous β€” Event Emitter implementation
  1. Idea: Map event -> listeners with on/off/once/emit.
  2. Complexity: O(n listeners) emit.
Solution
class EventEmitter {
  constructor() { this.events = new Map(); }
  on(evt, fn) {
    if (!this.events.has(evt)) this.events.set(evt, []);
    this.events.get(evt).push(fn);
    return () => this.off(evt, fn);
  }
  off(evt, fn) {
    if (!this.events.has(evt)) return;
    this.events.set(evt, this.events.get(evt).filter(f => f !== fn));
  }
  once(evt, fn) {
    const wrapper = (...args) => { fn(...args); this.off(evt, wrapper); };
    this.on(evt, wrapper);
  }
  emit(evt, ...args) {
    (this.events.get(evt) || []).slice().forEach(fn => fn(...args));
  }
}
πŸ§ͺ Miscellaneous β€” Implement Promise.all
  1. Idea: Return a promise that resolves when all resolve or rejects on first rejection.
  2. Complexity: O(n).
Solution
function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    const res = [];
    let done = 0;
    const n = promises.length;
    if (n === 0) resolve([]);
    promises.forEach((p, i) => {
      Promise.resolve(p).then(v => {
        res[i] = v;
        done++;
        if (done === n) resolve(res);
      }).catch(reject);
    });
  });
}
πŸ§ͺ Miscellaneous β€” Compose / Pipe utility functions
  1. Idea: Compose: right-to-left; Pipe: left-to-right.
  2. Complexity: O(n) where n functions.
Solution
const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
πŸ§ͺ Miscellaneous β€” Infinite scroll logic (sketch)
  1. Idea: Observe bottom via IntersectionObserver or check scroll pos throttled.
  2. Complexity: event-driven.
Sketch
// Use IntersectionObserver on sentinel element to load more:
// observer callback -> if intersecting -> fetch more -> append -> move sentinel.
πŸ§ͺ Miscellaneous β€” Retry mechanism with delay
  1. Idea: Recursive/promise loop with exponential backoff.
  2. Complexity: depends on tries.
Solution
async function retry(fn, tries = 3, delay = 500) {
  let attempt = 0;
  while (attempt < tries) {
    try {
      return await fn();
    } catch (e) {
      attempt++;
      if (attempt === tries) throw e;
      await new Promise(r => setTimeout(r, delay * (2 ** (attempt-1))));
    }
  }
}
πŸ§ͺ Miscellaneous β€” JSON diff tool (simple)
  1. Idea: DFS compare keys and values, list changed/added/removed.
  2. Complexity: O(n).
Solution
function diff(a, b, path = '') {
  const changes = [];
  const keys = new Set([...Object.keys(a || {}), ...Object.keys(b || {})]);
  for (const k of keys) {
    const p = path ? `${path}.${k}` : k;
    if (!(k in a)) changes.push({ type: 'added', key: p, value: b[k] });
    else if (!(k in b)) changes.push({ type: 'removed', key: p, value: a[k] });
    else if (typeof a[k] === 'object' && a[k] !== null && typeof b[k] === 'object' && b[k] !== null)
      changes.push(...diff(a[k], b[k], p));
    else if (a[k] !== b[k]) changes.push({ type: 'modified', key: p, from: a[k], to: b[k] });
  }
  return changes;
}
πŸ§ͺ Miscellaneous β€” setTimeout in Event Loop (explain)
  1. Idea: setTimeout puts callback in macrotask queue after minimum delay; microtasks (Promises) run first after current stack. Not code.
  2. Complexity: n/a
⚠️ **GitHub.com Fallback** ⚠️