Having a look at the HackerRank problem, the title is implying a HashTable might be a nice data structure to use for this problem ("Hash Tables: Ransom Note"). You might want to look up more about the theory, some examples in JS, (and even more/reference). JS objects can also be used as HashMaps, with a discussion of the pros and cons of this in other SO answers.
Essentially, with a (Hash)Map we can associate keys of some type, with values of the same or another type. Such as mapping strings -> integers. Setting and looking up a value in a map is in constant O(1)
time, whereas with an array, looking for a value (indexOf()
) is in linear O(n)
time. Using Map, the problem could be reduced to linear complexity. (Additionally, splice
is an 'expensive' O(n)
operation to remove an element from an array in JS).
Here is an idea / some pseudocode of how you might use a Map to solve the problem by mapping each word (string) to the count of how many occurrences we have of that word (integer).
map is an initially empty map
for every word in magazine:
if word not in map:
add word to map with count 1
else:
increment count of word in map
for every word in note:
if word not in map or count of word in map = 0:
show "No."
return
else:
decrement count of word in map (word has been used)
show "Yes."
return
Ignoring the hashtables for a moment, your code is a bit unnecessarily complicated in places. We don't actually need two nested for-loops. Only one that goes through all words in note
and removes them from magazine
array as we use them up. This removes the need for all the nested if- conditions and the boolean flag isRansom
. Finally, if you have something that looks like at the end of a function:
if(someBooleanValue) {
return true;
}
This can be replaced by:
return someBooleanValue;
Check also the parameter and return types of the function: in the HackerRank problem, magazine
and note
are already string arrays, and the function is not expected to return a boolean value, merely print to the console. With that in mind, here is how it could be done:
function checkMagazine(magazine, note) {
for (let word of note) {
let i = magazine.indexOf(word);
if (i == -1) {
console.log("No")
return;
}
magazine.splice(i, 1);
}
console.log('Yes');
}
Note that despite there being no nested for-loops, it is still quadratic in complexity due to the outer loop (for every word in note), and the linear complexity of splice
and indexOf
inside this loop.