English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

nu

visitante
1 / ?

Taxas de Crescimento, Não Custos Absolutos

Big O: Medindo Como O Custo Cresce Rapidamente

A notação Big O mede a taxa de crescimento do custo do algoritmo - não o custo absoluto.

A pergunta que a Big O responde: ao dobro do tamanho do input N, o trabalho é dobrado? Quadruplicado? Ficou plano?

A 'O' significa 'ordem de grandeza'. A expressão dentro do parênteses descreve a forma da curva de crescimento.

Tabela de Crescimento Big O: operações em N=10, 100 e 1.000 para O(1), O(N) e O(N²)

Classes de complexidade chave:

- O(1) — constante: o custo não cresce. Exemplo: procurar um valor por índice em um array. Independentemente de o array ter 10 itens ou 10 milhões, uma consulta é uma consulta.

- O(N) — linear: o custo cresce com o input. Exemplo: ler todos os itens em uma lista uma vez. Duplique a lista, duplique as leituras.

- O(N²) — quadrática: o custo cresce como o quadrado do input. Exemplo: comparar todos os itens com todos os outros itens. Duplique N, quadrifique o trabalho.

Tabela de comparação de crescimento:

| N | O(1) | O(N) | O(N²) |

|---|------|------|-------|

| 10 | 1 | 10 | 100 |

| 100 | 1 | 100 | 10,000 |

| 1,000 | 1 | 1,000 | 1,000,000 |

Aos N=10 a diferença parece pequena. Aos N=1.000 o vão se torna enorme.

Compare O(N) com O(N²)

Use a tabela de comparação de crescimento acima.

Aos N=1.000: O(N) requer 1.000 operações. O(N²) requer 1.000.000 operações.

Aos N=1.000, quantas vezes mais operações o O(N²) requer em comparação com o O(N)? Mostre seu trabalho.

Como a Estrutura do Código Revela Complexidade

Como Identificar Big O a Partir do Código

Big O esconde na forma da sua código. Quatro padrões cobrem a maioria dos casos:

Laço único sobre N itens: O(N)

# O(N): uma passagem pela lista
for item in list_of_n_items:
    process(item)

Laços aninhados, cada um com N itens: O(N²)

# O(N²): cada item sendo parado com cada outro item
for item_a in list_of_n_items:
    for item_b in list_of_n_items:
        compare(item_a, item_b)

Consulta de tempo constante: O(1)

Acesso a índice de array, consulta em tabela hash — um passo independente do tamanho.

Dividir e vencer (cortar o problema pela metade a cada etapa): O(log N)

Busca binária: cada verificação reduz a metade dos itens restantes.

---

Big O escondido: uma lista dentro de um laço

# Isso parece O(N) mas na verdade é O(N²)
visited = []
for item in list_of_n_items:
    if item not in visited:   # escaneia todos os elementos de visited: O(N)
        visited.append(item)  # o todo o loop: O(N²)

A linha if item not in visited escaneia todos os elementos de visited em cada iteração. Um escaneamento de lista custa O(N). Um laço que corre N vezes, cada um fazendo O(N) de trabalho: O(N) × O(N) = O(N²).

Este padrão aparece em 1.000+ projetos de código aberto. A solução leva apenas um caractere: substitua visited = [] por visited = set(). A verificação de membro de conjunto custa O(1), não O(N). Uma mudança. Mesmos resultados. 1.000× mais rápido em N=1.000.

Classifique e Corrija Este Código

Leia este código:

result = []
for name in student_names:
    if name not in result:
        result.append(name)
Qual é a complexidade Big O deste código? Explica por que a linha `if name not in result` o torna caro. Em seguida, reescreva o código para torná-lo O(N).

Teoria Encontra a Prática

Big O no Bairro

Big O não é apenas teoria. Ele separa programas que concluem em segundos de programas que levam 17 minutos - no mesmo trabalho exato.

Exemplo real: detecção de ciclo de dependência em um sistema de compilação.

Quando você instala software, seu computador resolve um gráfico de dependências: o pacote A precisa de B, B precisa de C e assim por diante. Um sistema de compilação verifica esse gráfico para detectar ciclos.

Um algoritmo de detecção de ciclo O(N²) funciona bem com N=100 pacotes. Com N=50.000 pacotes (um projeto real): leva 17 minutos. A correção O(N): 10 segundos.

Este defeito exato existe no GHC (compilador de Haskell), pip (gerenciador de pacotes Python), Maven (sistema de compilação Java), Cargo (gerenciador de pacotes Rust) e em mais de 1.000 outros projetos.

Não porque seus autores eram descuidados. visited = [] foi escrito quando N era pequeno. O código se calcificou. N cresceu. Ninguém percebeu até o build levar meia hora.

Big O é a linguagem que permite nomear o que aconteceu - e corrigi-lo.

---

Quer ir mais fundo? Nosso curso não-Hamming inclui um capítulo completo sobre Big O, MOAD-0001 (um defeito O(N²) realmente encontrado em 1.000 projetos de código aberto), e por que nomear um padrão permite que você o encontre em todos os lugares. Confira [O Capítulo Faltante: Complexidade Algorítmica](/en/un/unhamming_algorithmic_complexity).

Adivinhe os Tempos de Compilação

Um sistema de compilação usa detecção de ciclo O(N²).

Tempos de compilação medidos:

- N=100 pacotes: 0,01 segundos

- N=1.000 pacotes: 1 segundo

Para O(N²): o tempo aumenta proporcionalmente a (N_new / N_old)².

Para O(N): o tempo aumenta proporcionalmente a (N_new / N_old).

Usando essas fórmulas e dados medidos: (A) com N=10.000, quanto tempo leva a versão O(N²)? (B) após uma correção O(N), usando N=1.000 como base, quanto tempo leva a versão O(N) em N=10.000? Mostre o trabalho para ambos.