Guia Pleno

Primeiro você faz os treinos (entender o porquê do código). Depois você faz exercícios no compilador e só avança quando passar nos testes.

Treinos

Sliding Window (sem repetição)

Janela que expande e contrai mantendo contagem/últimos índices para evitar repetição.

Longest Substring (ideia)

1
export function longestSubstringNoRepeatIdea(s) {
2
  const last = new Map();
3
  let best = 0;
4
  let start = 0;
5
  for (let i = 0; i < s.length; i++) {
6
    const ch = s[i];
7
    if (last.has(ch) && last.get(ch) >= start) start = last.get(ch) + 1;
8
    last.set(ch, i);
9
    best = Math.max(best, i - start + 1);
10
  }
11
  return best;
12
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Dois ponteiros (área máxima)

Mover a borda limitante correta maximiza a chance de aumentar a área.

Container With Most Water (ideia)

1
export function maxAreaIdea(h) {
2
  let i = 0, j = h.length - 1;
3
  let best = 0;
4
  while (i < j) {
5
    const area = Math.min(h[i], h[j]) * (j - i);
6
    if (area > best) best = area;
7
    if (h[i] < h[j]) i++;
8
    else j--;
9
  }
10
  return best;
11
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Binary Search com invariantes

O erro mais comum é off-by-one. A regra é manter o intervalo (lo, hi) consistente.

Rotated Search (ideia)

1
export function searchRotatedIdea(a, x) {
2
  let lo = 0, hi = a.length - 1;
3
  while (lo <= hi) {
4
    const mid = lo + Math.floor((hi - lo) / 2);
5
    if (a[mid] === x) return mid;
6
    if (a[lo] <= a[mid]) {
7
      if (a[lo] <= x && x < a[mid]) hi = mid - 1; else lo = mid + 1;
8
    } else {
9
      if (a[mid] < x && x <= a[hi]) lo = mid + 1; else hi = mid - 1;
10
    }
11
  }
12
  return -1;
13
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Lower Bound (hi exclusivo)

1
export function lowerBound(arr, target) {
2
  let lo = 0;
3
  let hi = arr.length;
4
 
5
  while (lo < hi) {
6
    const mid = lo + Math.floor((hi - lo) / 2);
7
    if (arr[mid] < target) lo = mid + 1;
8
    else hi = mid;
9
  }
10
 
11
  return lo;
12
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Sorting (Merge Sort e Quick Sort)

Escolher a estratégia certa: estabilidade do merge sort e praticidade do quick sort.

Quick Sort (ideia)

1
export function quickSortIdea(a) {
2
  if (a.length <= 1) return a.slice();
3
  const p = a[0];
4
  const left = [], eq = [], right = [];
5
  for (const x of a) {
6
    if (x < p) left.push(x);
7
    else if (x > p) right.push(x);
8
    else eq.push(x);
9
  }
10
  return quickSortIdea(left).concat(eq, quickSortIdea(right));
11
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Linked List (ponteiros)

Reversão e detecção de ciclo com cuidado de ponteiros e variáveis auxiliares.

Reverse (ideia)

1
export function reverseListIdea(head) {
2
  let prev = null;
3
  let cur = head;
4
  while (cur) {
5
    const nxt = cur.next;
6
    cur.next = prev;
7
    prev = cur;
8
    cur = nxt;
9
  }
10
  return prev;
11
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Cycle (Floyd)

1
export function hasCycleIdea(head) {
2
  let slow = head, fast = head;
3
  while (fast && fast.next) {
4
    slow = slow.next;
5
    fast = fast.next.next;
6
    if (slow === fast) return true;
7
  }
8
  return false;
9
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Graphs: BFS/DFS em matriz

Visitar componentes conectados mantendo visited e limites da matriz.

Contar ilhas (ideia DFS)

1
export function countIslandsIdea(g) {
2
  const H = g.length, W = g[0]?.length ?? 0;
3
  const seen = Array.from({ length: H }, () => Array(W).fill(false));
4
  const dirs = [[1,0],[-1,0],[0,1],[0,-1]];
5
  const dfs = (r, c) => {
6
    const stack = [[r, c]];
7
    seen[r][c] = true;
8
    while (stack.length) {
9
      const [x, y] = stack.pop();
10
      for (const [dx, dy] of dirs) {
11
        const nx = x + dx, ny = y + dy;
12
        if (nx>=0 && nx<H && ny>=0 && ny<W && g[nx][ny] === "1" && !seen[nx][ny]) {
13
          seen[nx][ny] = true;
14
          stack.push([nx, ny]);
15
        }
16
      }
17
    }
18
  };
19
  let count = 0;
20
  for (let i = 0; i < H; i++) {
21
    for (let j = 0; j < W; j++) {
22
      if (g[i][j] === "1" && !seen[i][j]) { count++; dfs(i,j); }
23
    }
24
  }
25
  return count;
26
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Trees: Validate BST

Usar in-order crescente ou limites min/max para validar BST.

Limites min/max (ideia)

1
export function isValidBstIdea(root) {
2
  const go = (node, lo, hi) => {
3
    if (!node) return true;
4
    if ((lo !== null && node.val <= lo) || (hi !== null && node.val >= hi)) return false;
5
    return go(node.left, lo, node.val) && go(node.right, node.val, hi);
6
  };
7
  return go(root, null, null);
8
}

Clique em uma linha destacada para ver o motivo daquela escolha.

Exercícios recomendados desta seção

Exercícios