151. Reverse Words in a String
The problem:
Given an input string s, reverse the order of the words.
A word is defined as a sequence of non-space characters. The words in s will be separated by at least one space.
Return a string of the words in reverse order concatenated by a single space.
Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.
For this one I came up with three solutions:
The “I’m too busy for this sh*t man”
var reverseWords = function(s) {
return s.trim().split(" ").reverse().filter((word) => word.replace(/ /g, "") !== "").join(" ");
};
Results:
Runtime: 1ms
Memory: 54.96mb
Beats: 84.32%
Let’s explain it:
var reverseWords = function(s) {
return s.trim() // We remove the excess of spaces at the start and end of the string
.split(" ") // We convert it to an array by splitting it on every space.
.reverse() // Reverse the sh*t out of it
.filter((word) // Since we know there's a lot of extra spaces
=> word // There will be items in the array that are just empty spaces
.replace(/ /g, "") !== "") //We filter them using a regex.
.join(" "); // finally we join them with spaces.
};
One liners are cool but this is not optimized at all.
The One that i thought that it would perform better but it’s actually worse
This happens to me way too often, at this point I find it just funny.
Let’s see it:
var reverseWords = function(s) {
const arr = s.split(" "); // Split the s into an array
const length = arr.length; // Get the length
let ans = [];
let i = 0;
while(i < length) {
/*
In every iteration we replace spaces for nothing.
*/
const word = arr[i].replace(/ /g, "");
if(word !== "") { // if the word has nothing in it, we ignore it
ans.unshift(word); // if it has something, we add it to the start of the array.
}
i++
}
return ans.join(" "); // We simply join the ans array with spaces for response.
};
We are actually doing worse than the first one linner, but it makes sense:
We are creating a new array, pushing items inside of it, then converting that array into a string…
Results:
Runtime: 3ms
Memory: 55.11mb
Beats: 37.73%
The “Optimal”
For this one, right after i submitted the last one I went “Oh my, I’m dumb”
You see, we were doing almost everything correctly, except for one thing:
We don’t need to use an array to store the words
/*
This is almost the exact same code up until the next comment:
*/
var reverseWords = function(s) {
const arr = s.split(" ");
const length = arr.length;
let ans = "" // This variable is a string now.
let i = 0;
while(i < length) {
const word = arr[i].replace(/ /g, "");
if(word !== "") {
ans = word + " " + ans // We just add the new word with an space before the contents of the ans variable
}
i++
}
return ans.trim(); // We are definitely having an extra space, we remove it with trim()
};
Results:
Runtime: 0ms
Memory: 57.2mb
Beats: 100%
Interestingly enough, we are actually worse in the memory department, but hey, if I cared about memory I would be doing these in an actually great programming language instead of JavaScript!