awesome-everything RU
↑ Back to the climb

Algorithms from zero

Arrays and strings: code reading

Crux Read real two-pointer, sliding-window, prefix-sum, and in-place snippets, then predict the output, name the complexity, or spot the bug a test would catch.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min

The pattern is easy to recite and easy to break. Read each snippet the way you would in a review: trace the pointers, check the boundary, and decide whether the loop does what its author thinks it does.

Goal

Practise reading the unit’s patterns in code — predicting output, naming the true complexity, and catching the off-by-one or missing-precondition bug before it ships.

Snippet 1 — the variable-size window

function minSubarrayLen(arr, target) {
  let left = 0, sum = 0, best = Infinity;
  for (let right = 0; right < arr.length; right++) {
    sum += arr[right];
    while (sum >= target) {
      best = Math.min(best, right - left + 1);
      sum -= arr[left];
      left++;
    }
  }
  return best === Infinity ? 0 : best;
}
// minSubarrayLen([2, 3, 1, 2, 4, 3], 7)
Quiz

What does this call return, and what is the algorithm's time complexity?

Snippet 2 — in-place compaction

function removeVal(arr, val) {
  let write = 0;
  for (let read = 0; read < arr.length; read++) {
    if (arr[read] !== val) {
      arr[write] = arr[read];
      write++;
    }
  }
  return write;
}
// const a = [3, 2, 2, 3]; const k = removeVal(a, 3);
Quiz

After the call, what is k, and what is the state of the first k cells of a?

Snippet 3 — opposite-ends two-sum

function twoSum(arr, target) {
  let left = 0, right = arr.length - 1;
  while (left < right) {
    const sum = arr[left] + arr[right];
    if (sum === target) return [left, right];
    else if (sum < target) left++;
    else right--;
  }
  return null;
}
// twoSum([8, 2, 5, 1, 7], 9)
Quiz

The array [8, 2, 5, 1, 7] is not sorted. A correct pair summing to 9 exists (8 + 1, or 2 + 7). What does this code actually return, and why?

Snippet 4 — prefix-sum range query

function buildPrefix(arr) {
  const p = new Array(arr.length + 1).fill(0);
  for (let i = 0; i < arr.length; i++) p[i + 1] = p[i] + arr[i];
  return p;
}
function rangeSum(p, i, j) { return p[j] - p[i - 1]; }
// const p = buildPrefix([2, 5, 1, 3, 4]);  // p = [0, 2, 7, 8, 11, 15]
// rangeSum(p, 1, 3)  // intended: arr[1] + arr[2] + arr[3] = 9
Quiz

buildPrefix is correct, but rangeSum has an off-by-one bug. What does rangeSum(p, 1, 3) return, and what is the fix?

Recap

Reading the patterns in code is where the bugs hide. The variable-size window is O(n) because left only moves forward — the inner while is amortized, not nested. In-place compaction guarantees only a[0..k-1]; the tail is stale by contract. Opposite-ends two-sum is unsound on unsorted input even when it accidentally returns a pair. And prefix-sum queries live or die on the n+1 convention: p[k] is the sum of the first k elements, so the range formula is p[j+1] − p[i]. Trace the pointers and check the boundary before you trust the loop.

Continue the climb ↑Arrays and strings: build a log query engine
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.