151. Reverse Words in a String
El problema:
Dado un string de input s, invierte el orden de las palabras.
Una palabra se define como una secuencia de caracteres no espaciales. Las palabras en s estarán separadas por al menos un espacio.
Devuelve una string con las palabras en orden inverso, concatenadas por un solo espacio.
Ten en cuenta que s puede contener espacios al principio o al final, o múltiples espacios entre dos palabras. La string devuelta debe tener solo un espacio separando las palabras. No incluyas espacios extra.
Para este problema pensé en tres soluciones:
La solución “Estoy demasiado ocupado para esto”
var reverseWords = function(s) {
return s.trim().split(" ").reverse().filter((word) => word.replace(/ /g, "") !== "").join(" ");
};
Resultados:
Runtime: 1ms
Memoria: 54.96mb
Superior al: 84.32%
Voy a explicarlo:
var reverseWords = function(s) {
return s.trim() // Eliminamos los espacios sobrantes al inicio y al final de la string
.split(" ") // La convertimos en un array dividiéndola por cada espacio.
.reverse() // Invertimos el orden del array
.filter((word) // Como sabemos que hay muchos espacios extra
=> word // Habrá elementos en el array que son solo espacios vacíos
.replace(/ /g, "") !== "") // Los filtramos usando una expresión regex.
.join(" "); // Finalmente los unimos con espacios.
};
Usar one liners es cosa de chicos cool, pero esto no está para nada optimizado.
La que pensé que sería mejor pero en realidad es peor
Esto me pasa demasiado seguido, ya hasta me parece gracioso.
Veámoslo:
var reverseWords = function(s) {
const arr = s.split(" "); // Dividimos la string en un array
const length = arr.length; // Obtenemos la longitud
let ans = [];
let i = 0;
while(i < length) {
/*
En cada iteración reemplazamos los espacios por nada.
*/
const word = arr[i].replace(/ /g, "");
if(word !== "") { // Si la palabra está vacía, la ignoramos
ans.unshift(word); // Si tiene contenido, la agregamos al inicio del array.
}
i++
}
return ans.join(" "); // Finalmente unimos el array ans con espacios para la respuesta.
};
En realidad estamos obteniendo peores resultados que con el primer one-liner, pero tiene sentido:
Estamos creando un nuevo array, agregando elementos dentro de él y luego convirtiendo ese array en una string…
Resultados:
Runtime: 3ms
Memoria: 55.11mb
Superior al: 37.73%
La solución “Óptima”
Para esta solución, justo después de enviar la anterior me di cuenta del terrible error que cometí.
Verán, estábamos haciendo casi todo correctamente, excepto por una cosa:
No necesitamos usar un array para almacenar las palabras
/*
Este es casi el mismo código hasta el siguiente comentario:
*/
var reverseWords = function(s) {
const arr = s.split(" ");
const length = arr.length;
let ans = ""; // Ahora esta variable es un string.
let i = 0;
while(i < length) {
const word = arr[i].replace(/ /g, "");
if(word !== "") {
ans = word + " " + ans; // Simplemente agregamos la nueva palabra con un espacio antes del contenido de ans
}
i++;
}
return ans.trim(); // Definitivamente tenemos un espacio extra, lo eliminamos con trim()
};
Resultados:
Runtime: 0ms
Memoria: 57.2mb
Superior al: 100%
Curiosamente, en realidad estamos peor en el departamento de memoria, pero bueno, si me preocupara por la memoria estaría resolviendo estos problemas en un lenguaje de programación de verdad en lugar de en JavaScript.