Sliding Window (Fixed)

9 min de leituraMédioPython

Janela deslizante é dois ponteiros com uma regra: em vez de olhar todos os subarrays, você mantém um pedaço contíguo e vai ajustando as bordas. O que era O(n²) vira O(n).

O problema com a força bruta

Imagine que você precisa da maior soma de k elementos seguidos em um array. A solução óbvia é: para cada posição, somar os próximos k elementos e guardar o maior. Funciona, e é lento. Você refaz quase a mesma soma n vezes.

Repare no desperdício: as janelas [3,6,2] e [6,2,8] compartilham dois elementos. Se você já sabe a soma da primeira, a segunda custa uma soma e uma subtração, não três somas.

A ideia, em uma frase

Empurre a borda direita para incluir o elemento novo e a borda esquerda para descartar o que saiu. O estado da janela (a soma) é atualizado em O(1) a cada passo. Rode o visualizador abaixo, ele mostra exatamente isso, com o código acompanhando linha a linha. Use Expandir para ver o código lado a lado, bem grande.

Visualizador · maior soma de uma janela de tamanho k
passo 1 de 22
0
3
·
1
6
·
2
2
·
3
8
·
4
1
·
5
4
·
6
1
·
7
5
·

Janela vazia. esquerda e direita começam em 0.

Pseudocódigo
1função melhor_soma(nums, k):
2 soma ← 0
3 melhor ← 0
4 esquerda ← 0
5 para direita de 0 até n - 1:
6 soma ← soma + nums[direita]
7 se direita >= k - 1:
8 melhor ← máx(melhor, soma)
9 soma ← soma - nums[esquerda]
10 esquerda ← esquerda + 1
11 retorna melhor
esquerda0
direita-
soma0
melhor0
Velocidade1x

Edite o array e o k acima, a animação e o código se ajustam. Este é o caso de tamanho fixo: a janela sempre tem k elementos, então a cada passo entra um pela direita e sai um pela esquerda.

Janela fixa vs. variável

O exemplo acima tem tamanho travado. Existe também a janela variável, em que a direita sempre avança e a esquerda só se move enquanto a janela for inválida, é assim que você resolve "maior substring sem repetir caracteres" ou "menor subarray com soma ≥ alvo". Veja essa versão na página Sliding Window (Dynamic).

Fixa

Você sabe o tamanho de antemão. Entra um, sai um.

for direita in range(n):
    soma += nums[direita]
    if direita >= k - 1:
        melhor = max(melhor, soma)
        soma -= nums[direita - k + 1]
Variável

O tamanho depende de uma condição. Encolhe até voltar a valer.

while invalida(janela):
    soma -= nums[esquerda]
    esquerda += 1

Vídeo da aula

Direto do canal da comunidade Craft & Code Club · 18:24.

Problemas para praticar

Na ordem em que recomendamos resolver. Marque os que você já fez, fica salvo aqui.

Travou em algum passo? Traga sua questão para o Discord da comunidade ou para os encontros semanais.

Entrar
Concluiu este tópico?
Marque para acompanhar seu progresso na trilha.