- O teste no console do Needle In A Haystack verifica sua solução de busca de substring em segundos
- O problema pede o primeiro índice onde a needle aparece dentro da haystack, ou -1
- Duas soluções: uma janela deslizante manual com loops aninhados e o
indexOfintegrado - Teste com dois pares de exemplo: "pineapple pie" / "apple" e "a coffee bean" / "tea"
- Saída esperada no console: 4 para uma correspondência, -1 para nenhuma correspondência
Visão Geral do Problema e Fluxo de Trabalho no Console
O desafio Needle In A Haystack é um exercício clássico de entrevista de programação: dadas duas strings chamadas needle e haystack, retorne o índice onde a needle aparece pela primeira vez dentro da haystack. Se não aparecer, retorne -1. O console é seu ciclo de feedback mais rápido — escreva a função, registre duas chamadas de teste, execute o arquivo no terminal e leia os resultados imediatamente.
Destaques do Vídeo:
- Enunciado do problema: retorne o primeiro índice de
needledentro dehaystack, ou -1 - Solução 1: loops
foraninhados deslizando caractere por caractere pela string - Solução 2: um atalho de uma linha usando o método integrado
indexOf - Pares de teste: "pineapple pie" com "apple" (correspondência no índice 4) e "a coffee bean" com "tea" (sem correspondência, -1)
- Caso extremo: uma needle vazia retorna 0 por convenção
Antes de escrever qualquer lógica, configure suas variáveis de teste. Isso mantém sua sessão de console organizada e reprodutível:
const h1 = "pineapple pie";
const n1 = "apple";
const h2 = "a coffee bean";
const n2 = "tea";
| Par de Teste | Haystack | Needle | Saída Esperada | Por Quê |
|---|---|---|---|---|
| 1 | pineapple pie | apple | 4 | "apple" começa no índice 4 |
| 2 | a coffee bean | tea | -1 | "tea" nunca aparece |
Mantenha nomes de variáveis como h1, n1, h2, n2 consistentes em cada execução do console. Quando você compara as saídas entre as soluções manual e otimizada, nomes correspondentes tornam as divergências óbvias à primeira vista.
Solução 1: Janela Deslizante Manual
A primeira abordagem desliza sobre a string grande e compara caractere por caractere. Em cada posição inicial, verifique os próximos caracteres contra a needle. A primeira correspondência completa dá a resposta; se a varredura terminar sem correspondência, retorne -1.
function findNeedle(haystack, needle) {
if (needle.length === 0) return 0;
for (let i = 0; i <= haystack.length - needle.length; i++) {
let match = true;
for (let j = 0; j < needle.length; j++) {
if (haystack[i + j] !== needle[j]) {
match = false;
break;
}
}
if (match) return i;
}
return -1;
}
As principais decisões estruturais nesta solução:
| Componente | Papel | Detalhe |
|---|---|---|
| Verificação de limite | Caso extremo | Needle vazia retorna 0 imediatamente |
| Loop externo | Índice inicial | Executa enquanto i <= haystack.length - needle.length |
| Flag de correspondência | Suposição | Começa true, muda para false em caso de divergência |
| Loop interno | Comparação | Percorre os caracteres da needle, break para cedo |
| Retornar -1 | Falha | Loop externo terminou sem correspondência completa |
A condição do loop externo deve ser i <= haystack.length - needle.length. Erros de off-by-one aqui fazem com que você pule uma posição inicial válida no final da string ou leia além da string e quebre seu teste no console.
Solução 2: Otimizada com indexOf
Em vez de escrever loops aninhados manualmente, use a busca integrada. Chamar indexOf na haystack com a needle retorna o primeiro índice inicial se ele existir, ou -1 se não existir.
function findNeedleIndex(haystack, needle) {
if (needle.length === 0) return 0;
return haystack.indexOf(needle);
}
Manual (findNeedle)
- Loops for aninhados com uma flag de correspondência
- Mostra que você entende o algoritmo
- Melhor resposta quando pedem para "implementar você mesmo"
- Complexidade de tempo O(n × m)
Otimizada (findNeedleIndex)
- Retorno de uma linha com
indexOf - Código mais limpo e menos propenso a erros
- Melhor resposta quando a velocidade de entrega importa
- Saída idêntica em todos os pares de teste
Em uma entrevista ao vivo, apresente primeiro a solução manual para demonstrar raciocínio algorítmico e, em seguida, ofereça a versão com indexOf como a escolha mais limpa para produção. Ambas retornam os mesmos resultados, então diga isso explicitamente — mostra que você verificou a equivalência.
Teste no Console Passo a Passo
Execute ambas as soluções pelo mesmo fluxo de trabalho no console para confirmar um comportamento idêntico antes de considerar qualquer uma delas concluída.
Defina as variáveis de teste
Crie h1 = "pineapple pie", n1 = "apple", h2 = "a coffee bean", n2 = "tea" no topo do seu arquivo para que cada solução seja testada com entradas idênticas.
Registre a solução manual
Escreva console.log(findNeedle(h1, n1)) e console.log(findNeedle(h2, n2)) para exercitar o caminho de loops aninhados.
Execute o arquivo no terminal
Execute o arquivo com Node e leia a saída. Resultados esperados em ordem: 4, depois -1.
Registre a solução otimizada
Adicione console.log(findNeedleIndex(h1, n1)) e console.log(findNeedleIndex(h2, n2)) e execute novamente. As saídas devem coincidir: 4 e -1.
Confirme a equivalência e faça a limpeza
Se ambas as soluções concordarem em cada par, sua implementação está verificada. Remova logs duplicados ou mantenha-os rotulados para referência futura.
| Chamada no Console | Solução | Saída Esperada |
|---|---|---|
| findNeedle(h1, n1) | Manual | 4 |
| findNeedle(h2, n2) | Manual | -1 |
| findNeedleIndex(h1, n1) | Otimizada | 4 |
| findNeedleIndex(h2, n2) | Otimizada | -1 |
Quando todas as quatro chamadas de console imprimirem 4, -1, 4, -1 em ordem, ambas as implementações estão confirmadas como equivalentes e corretas para esses pares de teste. Esse é o seu sinal verde para prosseguir.
Checklist de Prática e Erros Comuns
Marcos de Domínio:
- Implementar a solução manual de janela deslizante de memória
- Tratar o caso extremo de needle vazia (retornar 0)
- Escrever a versão de uma linha com indexOf e explicar por que funciona
- Executar ambas as soluções no console e confirmar saídas idênticas
- Explicar em voz alta a diferença de complexidade de tempo
Erros comuns que quebram execuções no console:
| Erro | Sintoma | Correção |
|---|---|---|
Limite de loop errado (< em vez de <=) | Perde correspondência no final da string | Use i <= haystack.length - needle.length |
Sem break na divergência | Mais lento, mesmo resultado mas desperdiça recursos | Adicione break após definir match = false |
| Esquecer a verificação de needle vazia | Saída inesperada para "" | Retorne 0 quando needle.length === 0 |
| Trocar os argumentos | Sempre -1 | Mantenha a ordem: findNeedle(haystack, needle) |
Erros de digitação como haststack | ReferenceError no console | Use a grafia consistente: haystack |
Um erro frequente no console neste exercício é digitar haststack dentro da função enquanto o chamador passa haystack. O JavaScript trata isso como uma variável indefinida apenas se declarada errado, ou cria um bug silencioso — verifique a grafia em ambos os lugares.
FAQ
Q: O que o teste no console do Needle In A Haystack realmente verifica?
Ele verifica se sua função retorna o primeiro índice onde a needle aparece dentro da haystack, ou -1 quando não há correspondência. Com os pares de teste padrão, uma execução correta imprime 4 para 'apple' em 'pineapple pie' e -1 para 'tea' em 'a coffee bean'.
Q: Por que uma needle vazia retorna 0?
Por convenção, uma string vazia é considerada como aparecendo no início de qualquer string, índice 0. Tanto a solução manual quanto a baseada em indexOf incluem essa verificação para que suas saídas permaneçam consistentes.
Q: Qual solução devo apresentar em uma entrevista?
Comece com a versão manual de loops aninhados para demonstrar que você entende o algoritmo subjacente e, em seguida, apresente a versão com indexOf como a alternativa mais limpa e pronta para produção. Mencionar que ambas produzem a mesma saída no console fortalece sua resposta.
Q: Qual é a complexidade de tempo de cada abordagem?
A solução manual de janela deslizante roda em O(n × m), onde n é o comprimento da haystack e m é o comprimento da needle, porque cada posição inicial pode comparar até m caracteres. A versão com indexOf delega o trabalho à busca integrada da linguagem.