Algoritmos & Estruturas de Dados

Roadmap completo de DSA para entrevistas e fundamentos de engenharia. Cada tópico inclui visualizadores interativos, complexidade e exercícios selecionados do LeetCode com dicas de resolução.

Easy
Medium
Hard
· 19 tópicos · 89 exercícios
01

Arrays & Strings

Sequência contígua na memória com acesso O(1) por índice. Strings são sequências de caracteres (imutáveis na maioria das linguagens). A base de quase todos os problemas de entrevista.

Acesso: O(1) · Busca: O(n) · Inserção/Remoção: O(n) (append: O(1) amortizado)

Two Sum

Encontra dois números que somam ao target usando hash map. O(n) tempo, O(n) espaço.

2
0
7
1
11
2
15
3
1
4
8
5
3
6
Hash Map: {}
1function twoSum(nums, target) {
2 const map = new Map();
3
4 for (let i = 0; i < nums.length; i++) {
5 // Calcula o complemento necessário
6 const complement = target - nums[i];
7
8 // Verifica se o complemento já foi visto
9 if (map.has(complement)) {
10 return [map.get(complement), i];
11 }
12
13 // Armazena o valor atual e seu índice
14 map.set(nums[i], i);
15 }
16
17 return [];
18}

Array: [2, 7, 11, 15, 1, 8, 3] — Target: 9

0/4

Exercícios LeetCode

5 problemas
Easy
Two Sum

Dica: Use hash map para lookup O(1) do complemento

Easy
Best Time to Buy and Sell Stock

Dica: Mantenha o mínimo visto até agora e calcule o lucro em cada passo

Medium
Product of Array Except Self

Dica: Dois passes: prefix product da esquerda e suffix product da direita

Medium
Container With Most Water

Dica: Two pointers das extremidades, movendo o ponteiro menor

Hard
Trapping Rain Water

Dica: Para cada posição, água = min(maxLeft, maxRight) - height. Use two pointers ou prefix max

02

Hash Tables

Estrutura que mapeia chaves a valores usando função hash. Inserção, busca e remoção em O(1) no caso médio. Pior caso O(n) com colisões.

Inserção: O(1) amortizado · Busca: O(1)* · Remoção: O(1)* (*caso médio)

Hash Table

Inserção com função hash e resolução de colisões por chaining.

0
[0]
1
[1]
2
[2]
3
[3]
4
[4]
5
[5]
6
[6]
Buckets: [0]: vazio [1]: vazio [2]: vazio [3]: vazio [4]: vazio [5]: vazio [6]: vazio
1class HashTable {
2 constructor(size = 7) {
3 this.buckets = new Array(size).fill(null).map(() => []);
4 this.size = size;
5 }
6
7 hash(key) {
8 let h = 0;
9 for (const ch of key) h = (h + ch.charCodeAt(0)) % this.size;
10 return h;
11 }
12
13 set(key, value) {
14 const idx = this.hash(key);
15 const bucket = this.buckets[idx];
16 // Verifica se a chave já existe (atualiza)
17 const existing = bucket.find(([k]) => k === key);
18 if (existing) existing[1] = value;
19 else bucket.push([key, value]);
20 }
21
22 get(key) {
23 const idx = this.hash(key);
24 const pair = this.buckets[idx].find(([k]) => k === key);
25 return pair ? pair[1] : undefined;
26 }
27}

Hash table com 7 buckets vazia

0/11

Exercícios LeetCode

5 problemas
Easy
Valid Anagram

Dica: Conte a frequência de cada caractere com hash map

Medium
Group Anagrams

Dica: Use a string ordenada como chave do hash map

Medium
Longest Consecutive Sequence

Dica: Coloque tudo num Set. Para cada início de sequência (n-1 não existe), conte o comprimento

Medium
Subarray Sum Equals K

Dica: Prefix sum + hash map: conta quantos prefix sums anteriores = prefixSum - k

Medium
LRU Cache

Dica: Hash map + doubly linked list. Map aponta para nodes da lista

03

Two Pointers

Técnica que usa dois ponteiros percorrendo o array (geralmente das extremidades para o centro, ou ambos do início). Reduz O(n²) para O(n).

Tempo: O(n) · Espaço: O(1)

Two Pointers — Two Sum II

Dois ponteiros convergem em array ordenado para encontrar par com soma alvo. O(n).

1
0
2
1
3
2
5
3
8
4
11
5
15
6
left: 0
right: 6
1function twoSumSorted(numbers, target) {
2 let left = 0;
3 let right = numbers.length - 1;
4
5 while (left < right) {
6 const sum = numbers[left] + numbers[right];
7
8 if (sum === target) {
9 return [left, right];
10 } else if (sum < target) {
11 // Soma muito pequena, avança esquerda
12 left++;
13 } else {
14 // Soma muito grande, recua direita
15 right--;
16 }
17 }
18
19 return [-1, -1];
20}

Array ordenado. Target = 13. left=0, right=6

0/6

Exercícios LeetCode

4 problemas
Easy
Valid Palindrome

Dica: left e right convergem, ignorando não-alfanuméricos

Medium
Two Sum II (Sorted)

Dica: Two pointers clássico: soma < target → left++, soma > target → right--

Medium
3Sum

Dica: Ordene, fixe um elemento, use two pointers no restante. Pule duplicatas

Medium
Container With Most Water

Dica: Mova sempre o ponteiro com menor altura (não pode melhorar mantendo ele)

04

Sliding Window

Janela que desliza sobre uma sequência, mantendo um estado agregado. Evita recalcular do zero a cada posição. Ideal para subarrays/substrings contíguos.

Tempo: O(n) · Espaço: O(1) ou O(k)

Sliding Window — Max Sum Subarray

Janela deslizante de tamanho fixo para encontrar soma máxima. O(n).

2
0
1
1
5
2
1
3
3
4
2
5
8
6
1
7
3
8
1function maxSumSubarray(arr, k) {
2 let windowSum = 0;
3
4 // Soma da primeira janela
5 for (let i = 0; i < k; i++) {
6 windowSum += arr[i];
7 }
8 let maxSum = windowSum;
9
10 // Desliza a janela
11 for (let i = k; i < arr.length; i++) {
12 // Remove elemento que saiu, adiciona novo
13 windowSum = windowSum - arr[i - k] + arr[i];
14
15 // Atualiza o máximo
16 maxSum = Math.max(maxSum, windowSum);
17 }
18
19 return maxSum;
20}

Array: [2, 1, 5, 1, 3, 2, 8, 1, 3] — Janela de tamanho k=3

0/10

Exercícios LeetCode

5 problemas
Easy
Best Time to Buy and Sell Stock

Dica: Sliding window degenerado: mantenha mínimo à esquerda, calcule lucro

Medium
Longest Substring Without Repeating Characters

Dica: Janela variável + Set/Map. Quando encontrar duplicata, encolha a janela pela esquerda

Medium
Permutation in String

Dica: Janela fixa do tamanho de s1. Compare frequências de caracteres

Hard
Minimum Window Substring

Dica: Janela variável: expanda pela direita até conter tudo, encolha pela esquerda para minimizar

Hard
Sliding Window Maximum

Dica: Monotonic deque: mantém índices em ordem decrescente de valor

06

Prefix Sum

Pré-computa somas acumuladas para responder consultas de range em O(1). Base para muitos problemas de subarray e programação competitiva.

Construção: O(n) · Consulta: O(1)

Prefix Sum

Pré-computa somas acumuladas para consultas de range em O(1).

3
0
1
1
4
2
1
3
5
4
9
5
2
6
6
7
prefix: [0]
1function buildPrefixSum(arr) {
2 const prefix = [0];
3
4 // Constrói o array de prefix sum
5 for (let i = 0; i < arr.length; i++) {
6 prefix.push(prefix[i] + arr[i]);
7 }
8
9 return prefix;
10}
11
12// Consulta de range em O(1)
13function rangeSum(prefix, left, right) {
14 return prefix[right + 1] - prefix[left];
15}

Array original: [3, 1, 4, 1, 5, 9, 2, 6]

0/10

Exercícios LeetCode

4 problemas
Easy
Running Sum of 1d Array

Dica: Implementação direta de prefix sum

Medium
Subarray Sum Equals K

Dica: prefix[j] - prefix[i] = k ↔ prefix[i] = prefix[j] - k. Use hash map

Easy
Range Sum Query - Immutable

Dica: Pré-compute prefix sum no construtor, responda queries em O(1)

Medium
Product of Array Except Self

Dica: Prefix product pela esquerda × suffix product pela direita

07

Linked Lists

Coleção de nós onde cada nó aponta para o próximo. Inserção/remoção em O(1) dado o ponteiro, mas acesso por índice é O(n). Trade-off oposto ao array.

Acesso: O(n) · Busca: O(n) · Inserção/Remoção: O(1)* (*dado o ponteiro)

Reverse Linked List

Inverte uma linked list iterativamente com 3 ponteiros. O(n).

12345curr
curr
1function reverseList(head) {
2 let prev = null;
3 let curr = head;
4
5 while (curr !== null) {
6 // Salva o próximo nó
7 const next = curr.next;
8
9 // Inverte o ponteiro
10 curr.next = prev;
11
12 // Avança prev e curr
13 prev = curr;
14 curr = next;
15 }
16
17 // prev é o novo head
18 return prev;
19}

Lista original: 1 → 2 → 3 → 4 → 5

0/16

Exercícios LeetCode

5 problemas
Easy
Reverse Linked List

Dica: Três ponteiros: prev, current, next. Inverta os links iterativamente

Easy
Merge Two Sorted Lists

Dica: Use dummy head. Compare e avance o ponteiro menor

Easy
Linked List Cycle

Dica: Floyd's tortoise and hare: slow (1 passo) e fast (2 passos). Se encontram → ciclo

Medium
Reorder List

Dica: 3 passos: encontre o meio, inverta segunda metade, intercale as duas metades

Hard
Merge k Sorted Lists

Dica: Min-heap com k elementos (um de cada lista). Extraia o mínimo e insira o próximo

08

Stacks & Queues

Stack: LIFO (Last In, First Out). Queue: FIFO (First In, First Out). Fundamentais para parsing, BFS, DFS e problemas de ordem.

Push/Pop/Enqueue/Dequeue: O(1)

Valid Parentheses

Valida parênteses usando stack. Push aberturas, pop e compare fechamentos.

vazio
input: ({[]})
posição: 0
1function isValid(s) {
2 const stack = [];
3 const pairs = { ')': '(', ']': '[', '}': '{' };
4
5 for (const ch of s) {
6 if ('([{'.includes(ch)) {
7 // Abertura: push na stack
8 stack.push(ch);
9 } else {
10 // Fechamento: verifica match
11 if (stack.length === 0 || stack[stack.length - 1] !== pairs[ch]) {
12 return false;
13 }
14 // Match: pop da stack
15 stack.pop();
16 }
17 }
18
19 // Válido se stack vazia
20 return stack.length === 0;
21}

Validar: "({[]})"

0/7

Exercícios LeetCode

5 problemas
Easy
Valid Parentheses

Dica: Stack: push abertura, pop e compare ao encontrar fechamento

Medium
Min Stack

Dica: Dois stacks: um normal e um que rastreia o mínimo atual

Medium
Evaluate Reverse Polish Notation

Dica: Stack de operandos. Ao encontrar operador: pop dois, calcule, push resultado

Medium
Daily Temperatures

Dica: Monotonic stack decrescente. Ao encontrar temp maior: pop e calcule distância

Hard
Largest Rectangle in Histogram

Dica: Monotonic stack crescente. Para cada barra: calcule largura usando stack

09

Trees (Binary Tree & BST)

Estrutura hierárquica com nós e arestas. Binary Search Tree (BST) mantém: esquerda < raiz < direita, permitindo busca em O(log n) quando balanceada.

BST balanceada — Busca/Inserção/Remoção: O(log n)

BST In-Order Traversal

Percorre BST em ordem (L → Root → R), produzindo elementos ordenados.

1510255122030
Atual
Visitado
1function inOrderTraversal(root) {
2 const result = [];
3
4 function inOrder(node) {
5 if (node === null) return;
6
7 // Visita subárvore esquerda
8 inOrder(node.left);
9
10 // Processa o nó atual
11 result.push(node.val);
12
13 // Visita subárvore direita
14 inOrder(node.right);
15 }
16
17 inOrder(root);
18 return result; // Retorna valores em ordem crescente
19}

BST com 7 nós. In-order traversal: L → Root → R

0/15

Exercícios LeetCode

5 problemas
Easy
Invert Binary Tree

Dica: Recursão: troque left e right de cada nó, recursivamente

Easy
Maximum Depth of Binary Tree

Dica: return 1 + max(depth(left), depth(right)). Base: null → 0

Medium
Validate Binary Search Tree

Dica: Passe min/max bounds recursivamente. Ou: in-order traversal deve ser crescente

Medium
Binary Tree Level Order Traversal

Dica: BFS com fila. Processe level.length nós por nível

Hard
Serialize and Deserialize Binary Tree

Dica: Pre-order com marcador "null". Deserialize com fila/índice recursivo

10

Heaps / Priority Queue

Árvore binária completa onde cada pai ≥ filhos (max-heap) ou ≤ filhos (min-heap). Representada como array. Essencial para top-k, mediana e scheduling.

Insert: O(log n) · Extract Min/Max: O(log n) · Peek: O(1) · Build: O(n)

Min-Heap Insert

Insere elementos no min-heap com bubble up. O(log n) por inserção.

Atual
Visitado
1class MinHeap {
2 constructor() { this.heap = []; }
3
4 insert(val) {
5 // Adiciona no final
6 this.heap.push(val);
7
8 // Bubble up: troca com pai enquanto menor
9 let idx = this.heap.length - 1;
10 while (idx > 0) {
11 const parent = Math.floor((idx - 1) / 2);
12 if (this.heap[parent] <= this.heap[idx]) break;
13 // Troca com o pai
14 [this.heap[parent], this.heap[idx]] = [this.heap[idx], this.heap[parent]];
15 idx = parent;
16 }
17 }
18}

Inserindo valores: [5, 3, 8, 1, 4, 7, 2] em min-heap

0/25

Exercícios LeetCode

5 problemas
Easy
Kth Largest Element in a Stream

Dica: Min-heap de tamanho k. O topo é sempre o k-ésimo maior

Easy
Last Stone Weight

Dica: Max-heap. Extraia os dois maiores, insira a diferença se > 0

Medium
K Closest Points to Origin

Dica: Max-heap de tamanho k por distância. Ou quickselect para O(n) médio

Medium
Task Scheduler

Dica: Max-heap de frequências + cooldown queue. Simule ciclos

Hard
Find Median from Data Stream

Dica: Dois heaps: max-heap (metade menor) + min-heap (metade maior). Balance os tamanhos

11

Tries (Prefix Tree)

Árvore onde cada aresta representa um caractere. Busca por prefixo em O(m) onde m é o comprimento da palavra. Usado em autocomplete e spell checkers.

Insert: O(m) · Search: O(m) · Prefix Search: O(m)

Trie Insert

Insere palavras na Trie (prefix tree). Busca por prefixo em O(m).

root
Atual
Visitado
1class TrieNode {
2 constructor() {
3 this.children = {};
4 this.isEnd = false;
5 }
6}
7
8class Trie {
9 constructor() { this.root = new TrieNode(); }
10
11 insert(word) {
12 let node = this.root;
13
14 for (const ch of word) {
15 // Cria nó se não existe
16 if (!(ch in node.children)) {
17 node.children[ch] = new TrieNode();
18 }
19 // Avança para o filho
20 node = node.children[ch];
21 }
22
23 // Marca fim de palavra
24 node.isEnd = true;
25 }
26}

Inserir palavras: [cat, car, dog]

0/16

Exercícios LeetCode

3 problemas
Medium
Implement Trie (Prefix Tree)

Dica: Nó com children[26] + isEnd. Insert/search/startsWith iterativos

Medium
Design Add and Search Words

Dica: Trie + DFS. "." wildcard: tente todos os filhos recursivamente

Hard
Word Search II

Dica: Construa trie das palavras. DFS na grid usando o trie como guia. Prune ramos vazios

12

Graphs — BFS & DFS

Grafos modelam relações entre entidades. BFS explora nível a nível (menor caminho em grafos não-ponderados). DFS explora em profundidade (ciclos, componentes conexos).

BFS/DFS: O(V + E) · Espaço: O(V)

BFS — Busca em Largura

Explora todos os vizinhos antes de avançar para o próximo nível. Usa fila FIFO.

ABCDEFGHI
Atual
Visitado
Na fila/pilha
Fila: [A]
1function bfs(graph, start) {
2 const visited = new Set();
3 // Fila FIFO para controlar a ordem de visita
4 const queue = [start];
5
6 while (queue.length > 0) {
7 // Remove o primeiro da fila
8 const node = queue.shift();
9
10 if (visited.has(node)) continue;
11 // Marca o nó como visitado
12 visited.add(node);
13 console.log("Visitando:", node);
14
15 // Adiciona todos os vizinhos não visitados à fila
16 for (const neighbor of graph[node]) {
17 if (!visited.has(neighbor)) {
18 queue.push(neighbor);
19 }
20 }
21 }
22}
23
24// Exemplo de grafo como lista de adjacência
25const graph = {
26 A: ["B", "C"],
27 B: ["A", "D", "E"],
28 C: ["A", "F", "G"],
29 D: ["B", "H"],
30 E: ["B"],
31 F: ["C", "I"],
32 G: ["C"],
33 H: ["D"],
34 I: ["F"],
35};
36
37bfs(graph, "A");

Início: A adicionado à fila

0/18

Exercícios LeetCode

5 problemas
Medium
Number of Islands

Dica: DFS/BFS em cada "1" não visitado. Marque como visitado. Conte componentes

Medium
Clone Graph

Dica: DFS + hash map old→new. Crie clone ao visitar, conecte vizinhos recursivamente

Medium
Course Schedule

Dica: Detecte ciclo em grafo direcionado. Topological sort com DFS ou Kahn's (BFS)

Medium
Pacific Atlantic Water Flow

Dica: BFS/DFS reverso: comece dos oceanos e suba. Interseção = resposta

Hard
Word Ladder

Dica: BFS onde cada palavra é um nó. Vizinhos: palavras que diferem em 1 caractere

13

Algoritmos de Ordenação

Organizar elementos em ordem. Lower bound de comparação: Ω(n log n). Entender trade-offs entre estabilidade, espaço e caso médio vs pior caso.

Comparação: Ω(n log n) · Não-comparativo: O(n+k) ou O(d·n)

Merge Sort

Divide recursivamente e combina metades ordenadas. O(n log n) garantido.

10
47
31
22
28
46
42
13
16
51
40
11
1function mergeSort(arr) {
2 // Caso base: array de 1 elemento já está ordenado
3 if (arr.length <= 1) return arr;
4
5 // Divide o array ao meio
6 const mid = Math.floor(arr.length / 2);
7 const left = mergeSort(arr.slice(0, mid));
8 const right = mergeSort(arr.slice(mid));
9
10 // Combina as duas metades ordenadas
11 return merge(left, right);
12}
13
14function merge(left, right) {
15 const result = [];
16 let i = 0, j = 0;
17
18 // Compara elementos das duas metades e insere o menor
19 while (i < left.length && j < right.length) {
20 if (left[i] <= right[j]) {
21 result.push(left[i]);
22 i++;
23 } else {
24 result.push(right[j]);
25 j++;
26 }
27 }
28
29 // Copia os elementos restantes de cada metade
30 return result.concat(left.slice(i), right.slice(j));
31}

Array inicial

0/67

Exercícios LeetCode

4 problemas
Medium
Sort Colors

Dica: Dutch National Flag: 3 ponteiros (low, mid, high). Particione em 0s, 1s, 2s

Medium
Top K Frequent Elements

Dica: Counting + bucket sort por frequência. Ou heap de tamanho k

Medium
Kth Largest Element in an Array

Dica: Quickselect (partição do quicksort): O(n) médio. Ou min-heap de tamanho k

Medium
Merge Intervals

Dica: Ordene por start. Itere e merge se overlap (current.start <= last.end)

14

Recursão & Backtracking

Construir soluções incrementalmente e abandonar caminhos inválidos (pruning). Gera permutações, combinações e resolve constraint satisfaction problems.

Tempo: O(2ⁿ) ou O(n!) com pruning · Espaço: O(n) stack

Subsets — Backtracking

Gera todos os subsets de [1,2,3] usando árvore de decisão.

[][1][][1,2][1][2][][1,2,3][1,2][1,3][1][2,3][2][3][]
Atual
Visitado
1function subsets(nums) {
2 const result = [];
3
4 function backtrack(start, current) {
5 // Adiciona o subset atual ao resultado
6 result.push([...current]);
7
8 // Tenta incluir cada elemento restante
9 for (let i = start; i < nums.length; i++) {
10 current.push(nums[i]); // escolha
11 backtrack(i + 1, current); // explora
12 current.pop(); // desfaz (backtrack)
13 }
14 }
15
16 backtrack(0, []);
17 return result;
18}

Gerar todos os subsets de [1, 2, 3]

0/16

Exercícios LeetCode

5 problemas
Medium
Subsets

Dica: Para cada elemento: incluir ou não incluir. Backtrack gerando todas combinações

Medium
Permutations

Dica: Para cada posição, tente cada número não usado. Backtrack removendo do resultado

Medium
Combination Sum

Dica: Backtrack com reutilização. Ordene e pule se candidato > remaining target

Hard
N-Queens

Dica: Uma rainha por linha. Verifique coluna e diagonais. Use sets ou bitmask para O(1) check

Medium
Word Search

Dica: DFS na grid. Marque visitado, tente 4 direções, desmarque ao voltar (backtrack)

15

Programação Dinâmica

Resolve problemas com subproblemas sobrepostos e subestrutura ótima. Memoization (top-down) ou tabulação (bottom-up). Reduz complexidade exponencial para polinomial.

Tempo: O(estados × transição) · Espaço: O(estados)

Climbing Stairs (DP)

dp[i] = dp[i-1] + dp[i-2]. É Fibonacci! O(n) tempo, O(n) espaço.

0
1
2
3
4
5
6
1function climbStairs(n) {
2 // Cria tabela DP
3 const dp = new Array(n + 1);
4
5 // Casos base
6 dp[0] = 1; // 1 forma de ficar parado
7 dp[1] = 1; // 1 forma de subir 1 degrau
8
9 // Preenche bottom-up
10 for (let i = 2; i <= n; i++) {
11 dp[i] = dp[i - 1] + dp[i - 2];
12 }
13
14 return dp[n];
15}

Climbing Stairs: quantas formas de subir 6 degraus? (1 ou 2 passos)

0/13

Exercícios LeetCode

5 problemas
Easy
Climbing Stairs

Dica: dp[i] = dp[i-1] + dp[i-2]. É literalmente Fibonacci!

Medium
House Robber

Dica: dp[i] = max(dp[i-1], dp[i-2] + nums[i]). Roubar ou pular

Medium
Coin Change

Dica: dp[amount] = min(dp[amount - coin] + 1) para cada moeda. Unbounded knapsack

Medium
Longest Increasing Subsequence

Dica: O(n²): dp[i] = max(dp[j]+1) para j<i com arr[j]<arr[i]. O(n logn): patience sort

Medium
Edit Distance

Dica: 2D DP: dp[i][j] = custo para transformar s1[0..i] em s2[0..j]. 3 operações

16

Greedy Algorithms

Faz a escolha localmente ótima a cada passo, esperando encontrar o ótimo global. Funciona quando a "greedy choice property" é satisfeita.

Geralmente O(n log n) com sort + O(n) scan

Interval Scheduling (Greedy)

Seleciona máximo de atividades não-conflitantes. Ordena por fim.

012345678910CABDEFG
1function intervalScheduling(intervals) {
2 // Ordena por tempo de fim
3 intervals.sort((a, b) => a[1] - b[1]);
4
5 const selected = [];
6 let lastEnd = -Infinity;
7
8 for (const [start, end] of intervals) {
9 // Se não conflita com o último selecionado
10 if (start >= lastEnd) {
11 // Seleciona esta atividade
12 selected.push([start, end]);
13 lastEnd = end;
14 }
15 }
16
17 return selected;
18}

7 atividades ordenadas por fim. Greedy: escolha a que termina primeiro.

0/12

Exercícios LeetCode

5 problemas
Medium
Maximum Subarray

Dica: Kadane's: maxEndingHere = max(num, maxEndingHere + num). Greedy local → global

Medium
Jump Game

Dica: Mantenha o alcance máximo (farthest). Se i > farthest, impossível

Medium
Jump Game II

Dica: BFS implícito: a cada "nível" (range), calcule o próximo farthest. Conte níveis

Medium
Gas Station

Dica: Se total_gas >= total_cost, solução existe. Reset start quando tank < 0

Medium
Hand of Straights

Dica: Ordene. Use hash map de frequências. Para cada menor carta, tente formar grupo

17

Intervals

Problemas envolvendo intervalos [start, end]. Pattern: ordene por start ou end, depois itere verificando overlaps/merges.

Sort: O(n log n) + Scan: O(n) = O(n log n)

Merge Intervals

Ordena por start e merge intervalos sobrepostos. O(n log n).

0123456789101112131415161718[1,3][2,6][8,12][10,11][13,18]
1function mergeIntervals(intervals) {
2 // Ordena por start
3 intervals.sort((a, b) => a[0] - b[0]);
4
5 const merged = [intervals[0]];
6
7 for (let i = 1; i < intervals.length; i++) {
8 const last = merged[merged.length - 1];
9
10 // Verifica overlap
11 if (intervals[i][0] <= last[1]) {
12 // Merge: estende o end
13 last[1] = Math.max(last[1], intervals[i][1]);
14 } else {
15 // Sem overlap: novo intervalo
16 merged.push(intervals[i]);
17 }
18 }
19
20 return merged;
21}

5 intervalos ordenados por start.

0/10

Exercícios LeetCode

4 problemas
Medium
Merge Intervals

Dica: Ordene por start. Se current.start <= last.end: merge (max dos ends)

Medium
Insert Interval

Dica: Adicione antes, merge overlaps no meio, adicione depois. Três fases

Medium
Non-overlapping Intervals

Dica: Greedy: ordene por end. Conte conflitos (keep o que termina antes)

Medium
Minimum Number of Arrows to Burst Balloons

Dica: Ordene por end. Se balloon.start > arrow, nova flecha. Senão, já estoura

18

Bit Manipulation

Operações diretamente nos bits: AND, OR, XOR, shifts. Extremamente eficiente — uma instrução CPU. Usado em masks, flags e otimizações.

Operações bitwise: O(1)

Single Number (XOR)

XOR de todos: duplicados se cancelam, sobra o único. O(n) tempo, O(1) espaço.

0 em binário
0
7
0
6
0
5
0
4
0
3
0
2
0
1
0
0
1function singleNumber(nums) {
2 let result = 0;
3
4 // XOR de todos os elementos
5 for (const num of nums) {
6 result ^= num;
7 }
8
9 // Duplicados se cancelam (a^a=0)
10 // Resta apenas o único
11 return result;
12}

Array: [4, 1, 2, 1, 2]. Encontrar o número único usando XOR.

0/6

Exercícios LeetCode

5 problemas
Easy
Single Number

Dica: XOR todos: a^a=0, 0^b=b. Todos duplicados se cancelam, sobra o único

Easy
Number of 1 Bits

Dica: n & (n-1) remove o lowest set bit. Conte quantas vezes até n=0

Easy
Counting Bits

Dica: dp[i] = dp[i >> 1] + (i & 1). Ou dp[i] = dp[i & (i-1)] + 1

Easy
Reverse Bits

Dica: Extraia cada bit (n & 1), shift no resultado, shift no n. 32 iterações

Easy
Missing Number

Dica: XOR de 0..n com todos os elementos. Duplicados cancelam, sobra o faltante

19

Grafos Avançados

Topological Sort para DAGs, Union-Find para componentes conexos, Dijkstra para menores caminhos ponderados. Problemas que vão além de BFS/DFS simples.

Topo Sort: O(V+E) · Union-Find: O(α(n)) por operação · Dijkstra: O((V+E) log V)

Topological Sort (Kahn's)

Ordena nós de um DAG respeitando dependências. BFS com in-degree.

01234
Atual
Processado
Na fila
1function topologicalSort(numNodes, edges) {
2 // Constrói grafo e calcula in-degrees
3 const adj = Array.from({length: numNodes}, () => []);
4 const inDegree = new Array(numNodes).fill(0);
5
6 for (const [u, v] of edges) {
7 adj[u].push(v);
8 inDegree[v]++;
9 }
10
11 // Enfileira nós com in-degree 0
12 const queue = [];
13 for (let i = 0; i < numNodes; i++) {
14 if (inDegree[i] === 0) queue.push(i);
15 }
16
17 const order = [];
18
19 while (queue.length > 0) {
20 const node = queue.shift();
21 order.push(node);
22
23 // Reduz in-degree dos vizinhos
24 for (const neighbor of adj[node]) {
25 inDegree[neighbor]--;
26 // Se in-degree chega a 0, enfileira
27 if (inDegree[neighbor] === 0) {
28 queue.push(neighbor);
29 }
30 }
31 }
32
33 return order;
34}

Kahn's Topological Sort. In-degrees: {"0":0,"1":1,"2":1,"3":2,"4":1}

0/16

Exercícios LeetCode

5 problemas
Medium
Course Schedule II

Dica: Topological sort (Kahn's BFS): comece pelos nós com in-degree 0

Medium
Redundant Connection

Dica: Union-Find: adicione arestas uma a uma. Se find(u) == find(v), é redundante

Medium
Number of Provinces

Dica: Union-Find ou DFS na adjacency matrix. Conte quantos roots/componentes distintos existem

Medium
Network Delay Time

Dica: Dijkstra com min-heap. Retorne o max dos tempos mínimos

Medium
Find Eventual Safe States

Dica: Topological sort reverso: nós terminais são safe. Remova arestas de trás pra frente (ou DFS com 3 cores)