Guia Senior

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

Prefix Sum + Hashing (contagem de subarrays)

Contar subarrays com soma alvo usando prefixos acumulados e mapa de frequências.

Subarray Sum Equals K (ideia)

1
export function subarraySumIdea(nums, k) {
2
  const freq = new Map();
3
  freq.set(0, 1);
4
  let pref = 0, count = 0;
5
  for (const n of nums) {
6
    pref += n;
7
    count += freq.get(pref - k) ?? 0;
8
    freq.set(pref, (freq.get(pref) ?? 0) + 1);
9
  }
10
  return count;
11
}

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

Exercícios recomendados desta seção

Minimum Window Substring (janela variável)

Manter contadores do alvo e uma janela que expande/contrai até cobrir todos os caracteres.

Janela variável (ideia)

1
export function minWindowIdea(s, t) {
2
  const need = new Map();
3
  for (const ch of t) need.set(ch, (need.get(ch) ?? 0) + 1);
4
  let have = 0, needCount = t.length;
5
  let best = [0, Infinity];
6
  let l = 0;
7
  for (let r = 0; r < s.length; r++) {
8
    const c = s[r];
9
    if (need.has(c)) {
10
      const v = need.get(c) - 1;
11
      need.set(c, v);
12
      if (v >= 0) have++;
13
    }
14
    while (have === needCount) {
15
      if (r - l < best[1] - best[0]) best = [l, r + 1];
16
      const d = s[l++];
17
      if (need.has(d)) {
18
        const v = need.get(d) + 1;
19
        need.set(d, v);
20
        if (v > 0) have--;
21
      }
22
    }
23
  }
24
  return best[1] === Infinity ? "" : s.slice(best[0], best[1]);
25
}

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

Exercícios recomendados desta seção

Graphs: Topological (ciclo e ordenação)

Detectar ciclos e decidir ordem com Kahn (in-degree) ou DFS com marcas.

Kahn (ideia simplificada)

1
export function canFinishIdea(n, prereq) {
2
  const indeg = Array(n).fill(0);
3
  const adj = Array.from({ length: n }, () => []);
4
  for (const [a, b] of prereq) { adj[b].push(a); indeg[a]++; }
5
  const q = [];
6
  for (let i = 0; i < n; i++) if (indeg[i] === 0) q.push(i);
7
  let seen = 0;
8
  while (q.length) {
9
    const u = q.shift();
10
    seen++;
11
    for (const v of adj[u]) if (--indeg[v] === 0) q.push(v);
12
  }
13
  return seen === n;
14
}

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

Exercícios recomendados desta seção

Binary Search na Resposta

Buscar a menor resposta k que satisfaz um predicado monotônico.

Koko (ideia)

1
export function minSpeedIdea(piles, h) {
2
  let lo = 1, hi = Math.max(...piles);
3
  const ok = (k) => {
4
    let t = 0;
5
    for (const p of piles) t += Math.ceil(p / k);
6
    return t <= h;
7
  };
8
  while (lo < hi) {
9
    const mid = Math.floor((lo + hi) / 2);
10
    if (ok(mid)) hi = mid; else lo = mid + 1;
11
  }
12
  return lo;
13
}

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

Exercícios recomendados desta seção

Selection (Quick Select)

Selecionar o k-ésimo maior em média O(n) com partição.

Quick Select (ideia)

1
export function kthIdea(a, k) {
2
  const idx = a.length - k;
3
  const b = a.slice();
4
  let lo = 0, hi = b.length - 1;
5
  while (true) {
6
    const p = b[lo];
7
    let i = lo, j = hi, t;
8
    while (i <= j) {
9
      while (b[i] < p) i++;
10
      while (b[j] > p) j--;
11
      if (i <= j) { t = b[i]; b[i] = b[j]; b[j] = t; i++; j--; }
12
    }
13
    if (idx <= j) hi = j; else if (idx >= i) lo = i; else return b[idx];
14
  }
15
}

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

Exercícios recomendados desta seção

Clone Graph (lista de adjacência)

Clonar estrutura mantendo as listas de adjacência equivalentes.

DFS/BFS em adjacência (ideia)

1
export function cloneAdjIdea(adj) {
2
  const n = adj.length;
3
  const out = Array.from({ length: n }, () => []);
4
  for (let i = 0; i < n; i++) out[i] = adj[i].slice();
5
  return out;
6
}

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

Exercícios recomendados desta seção

Precisão e escala (BigInt + módulo)

Em strings grandes, o número de pares pode crescer como O(n²). Em JS, Number perde precisão; use BigInt.

Base para operações com BigInt

1
const MOD = 1000000007n;
2
 
3
export function modMul(a, b) {
4
  return (a * b) % MOD;
5
}
6
 
7
export function modAdd(a, b) {
8
  return (a + b) % MOD;
9
}

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

Exercícios recomendados desta seção

Trees: Lowest Common Ancestor (BST)

Explorar propriedade de BST para descer à esquerda/direita até encontrar o LCA.

LCA em BST (ideia)

1
export function lcaBstIdea(root, p, q) {
2
  let cur = root;
3
  while (cur) {
4
    if (p < cur.val && q < cur.val) cur = cur.left;
5
    else if (p > cur.val && q > cur.val) cur = cur.right;
6
    else return cur?.val ?? null;
7
  }
8
  return null;
9
}

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

Exercícios recomendados desta seção

Exercícios