- Las pruebas en la consola de Needle In A Haystack verifican tu solución de búsqueda de subcadenas en segundos
- El problema pide el primer índice donde la aguja (needle) aparece dentro del pajar (haystack), o -1
- Dos soluciones: una ventana deslizante manual con bucles anidados y el
indexOfintegrado - Prueba con dos pares de ejemplo: "pineapple pie" / "apple" y "a coffee bean" / "tea"
- Salida esperada en consola: 4 para una coincidencia, -1 si no hay coincidencia
Descripción General del Problema y Flujo de Consola
El desafío Needle In A Haystack es un ejercicio clásico de entrevistas de programación: dadas dos cadenas llamadas needle y haystack, devuelve el índice donde la aguja aparece por primera vez dentro del pajar. Si no aparece, devuelve -1. La consola es tu bucle de retroalimentación más rápido — escribe la función, registra dos llamadas de prueba, ejecuta el archivo en la terminal y lee los resultados de inmediato.
Aspectos destacados del video:
- Enunciado del problema: devolver el primer índice de
needledentro dehaystack, o -1 - Solución 1: bucles
foranidados deslizándose carácter por carácter a través de la cadena - Solución 2: un atajo de una línea usando el método integrado
indexOf - Pares de prueba: "pineapple pie" con "apple" (coincidencia en el índice 4), y "a coffee bean" con "tea" (sin coincidencia, -1)
- Caso límite: una aguja vacía devuelve 0 por convención
Antes de escribir cualquier lógica, configura tus variables de prueba. Esto mantiene tu sesión de consola organizada y reproducible:
const h1 = "pineapple pie";
const n1 = "apple";
const h2 = "a coffee bean";
const n2 = "tea";
| Par de Prueba | Pajar (Haystack) | Aguja (Needle) | Salida Esperada | Por qué |
|---|---|---|---|---|
| 1 | pineapple pie | apple | 4 | "apple" comienza en el índice 4 |
| 2 | a coffee bean | tea | -1 | "tea" nunca aparece |
Mantén nombres de variables como h1, n1, h2, n2 consistentes en cada ejecución de consola. Cuando compares salidas entre las soluciones manual y optimizada, los nombres coincidentes hacen que las discrepancias sean obvias de un vistazo.
Solución 1: Ventana Deslizante Manual
El primer enfoque se desliza sobre la cadena grande y compara carácter por carácter. En cada posición inicial, verifica los siguientes caracteres contra la aguja. La primera coincidencia completa da la respuesta; si el escaneo termina sin coincidencia, devuelve -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;
}
Las decisiones estructurales clave en esta solución:
| Componente | Rol | Detalle |
|---|---|---|
| Verificación de límite | Caso límite | Una aguja vacía devuelve 0 inmediatamente |
| Bucle externo | Índice inicial | Se ejecuta mientras i <= haystack.length - needle.length |
| Bandera de coincidencia | Suposición | Comienza en true, cambia a false ante una discrepancia |
| Bucle interno | Comparación | Recorre los caracteres de la aguja, break detiene antes |
| Retornar -1 | Fallo | El bucle externo terminó sin coincidencia completa |
La condición del bucle externo debe ser i <= haystack.length - needle.length. Los errores de un off-by-one aquí pueden omitir una posición inicial válida al final de la cadena o leer más allá de la cadena y hacer que falle tu prueba de consola.
Solución 2: Optimizada con indexOf
En lugar de escribir bucles anidados a mano, usa la búsqueda integrada. Llamar a indexOf sobre el pajar con la aguja devuelve el primer índice inicial si existe, o -1 si no existe.
function findNeedleIndex(haystack, needle) {
if (needle.length === 0) return 0;
return haystack.indexOf(needle);
}
Manual (findNeedle)
- Bucles for anidados con una bandera de coincidencia
- Demuestra que entiendes el algoritmo
- Mejor respuesta cuando piden "implémentalo tú mismo"
- Complejidad temporal O(n × m)
Optimizada (findNeedleIndex)
- Retorno de una línea con
indexOf - Código más limpio y menos propenso a errores
- Mejor respuesta cuando importa la velocidad de entrega
- Salida idéntica en todos los pares de prueba
En una entrevista en vivo, presenta primero la solución manual para demostrar pensamiento algorítmico, luego ofrece la versión con indexOf como la opción más limpia para producción. Ambas devuelven los mismos resultados, así que dilo explícitamente — muestra que verificaste la equivalencia.
Pruebas en Consola Paso a Paso
Ejecuta ambas soluciones a través del mismo flujo de consola para confirmar un comportamiento idéntico antes de dar por terminada cualquiera de las dos.
Define las variables de prueba
Crea h1 = "pineapple pie", n1 = "apple", h2 = "a coffee bean", n2 = "tea" al principio de tu archivo para que cada solución se pruebe con entradas idénticas.
Registra la solución manual
Escribe console.log(findNeedle(h1, n1)) y console.log(findNeedle(h2, n2)) para ejercitar la ruta de bucles anidados.
Ejecuta el archivo en la terminal
Ejecuta el archivo con Node y lee la salida. Resultados esperados en orden: 4, luego -1.
Registra la solución optimizada
Agrega console.log(findNeedleIndex(h1, n1)) y console.log(findNeedleIndex(h2, n2)), luego vuelve a ejecutar. Las salidas deben coincidir: 4 y -1.
Confirma la equivalencia y limpia
Si ambas soluciones coinciden en cada par, tu implementación está verificada. Elimina los registros duplicados o mantenlos etiquetados para referencia futura.
| Llamada de Consola | Solución | Salida Esperada |
|---|---|---|
| findNeedle(h1, n1) | Manual | 4 |
| findNeedle(h2, n2) | Manual | -1 |
| findNeedleIndex(h1, n1) | Optimizada | 4 |
| findNeedleIndex(h2, n2) | Optimizada | -1 |
Cuando las cuatro llamadas de consola impriman 4, -1, 4, -1 en orden, ambas implementaciones quedan confirmadas como equivalentes y correctas para estos pares de prueba. Esa es tu luz verde para continuar.
Lista de Práctica y Errores Comunes
Hitos de Dominio:
- Implementar la solución manual de ventana deslizante de memoria
- Manejar el caso límite de aguja vacía (retornar 0)
- Escribir la versión de una línea con indexOf y explicar por qué funciona
- Ejecutar ambas soluciones en la consola y confirmar salida idéntica
- Explicar en voz alta la diferencia de complejidad temporal
Errores comunes que rompen las ejecuciones de consola:
| Error | Síntoma | Solución |
|---|---|---|
Límite de bucle incorrecto (< en lugar de <=) | Omite la coincidencia al final de la cadena | Usa i <= haystack.length - needle.length |
Sin break en discrepancias | Más lento, mismo resultado pero desperdiciado | Agrega break después de poner match = false |
| Olvidar la verificación de aguja vacía | Salida inesperada para "" | Retorna 0 cuando needle.length === 0 |
| Intercambiar argumentos | Siempre -1 | Mantén el orden: findNeedle(haystack, needle) |
Errores tipográficos como haststack | ReferenceError en consola | Usa una ortografía consistente: haystack |
Un error frecuente de consola en este ejercicio es escribir haststack dentro de la función mientras el llamador pasa haystack. JavaScript lo trata como una variable no definida solo si se declara mal, o silenciosamente crea un bug — revisa dos veces la ortografía en ambos lugares.
Preguntas Frecuentes
Q: ¿Qué verifica realmente la prueba de consola de Needle In A Haystack?
Verifica que tu función devuelva el primer índice donde la aguja aparece dentro del pajar, o -1 cuando no hay coincidencia. Con los pares de prueba estándar, una ejecución correcta imprime 4 para 'apple' en 'pineapple pie' y -1 para 'tea' en 'a coffee bean'.
Q: ¿Por qué una aguja vacía devuelve 0?
Por convención, una cadena vacía se considera que aparece al inicio de cualquier cadena, en el índice 0. Tanto la solución manual como la basada en indexOf incluyen esta verificación para que sus salidas se mantengan consistentes.
Q: ¿Qué solución debería dar en una entrevista?
Comienza con la versión manual de bucles anidados para demostrar que entiendes el algoritmo subyacente, luego presenta la versión con indexOf como la alternativa más limpia y lista para producción. Mencionar que ambas producen la misma salida de consola fortalece tu respuesta.
Q: ¿Cuál es la complejidad temporal de cada enfoque?
La solución manual de ventana deslizante se ejecuta en O(n × m), donde n es la longitud del pajar y m es la longitud de la aguja, porque cada posición inicial puede comparar hasta m caracteres. La versión con indexOf delega el trabajo a la búsqueda integrada del lenguaje.