Here is the original problem, and here's my solution:
function main() {
var m_temp = readLine().split(' ');
var m = parseInt(m_temp[0]);
var n = parseInt(m_temp[1]);
magazine = readLine().split(' ');
ransom = readLine().split(' ');
var freqs = {}
for (var i = 0; i < m; i++){
freqs[magazine[i]] = (freqs[magazine[i]] || 0) + 1;
}
var result = "Yes"
for (var j = 0; j < n; j++){
if (freqs[ransom[j]] && freqs[ransom[j]] > 0){
freqs[ransom[j]] -= 1;
} else {
result = "No"
break;
}
}
console.log(result)
}
I wonder if there's a more efficient solution than this? Thanks! I understand forEach
could be used for code brevity, but I'm just using for loop for the extra performance benefit (https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead)
1 Answer 1
Your solution may work for valid inputs, but you are not checking invalid input situations such as when the ransom letter contains more words than the ones in the magazine:
if(n > m):
throw new Error("ransom can not be written from magazine");
You can even go further by checking if the first line corresponds to what it pretends to be:
if (magazine.length !== m)
throw new Error("Wrong words number in magazine");
if (ransom.length !== n)
throw new Error("Wrong words number in ransom");
You can refactor the above conditions in one single line:
if(n > m || agazine.length !== m || ransom.length !== n):
throw new Error("Invalid input");
-
\$\begingroup\$ Right, edge cases! ty \$\endgroup\$kdenz– kdenz2017年06月18日 15:24:29 +00:00Commented Jun 18, 2017 at 15:24
Explore related questions
See similar questions with these tags.
if (!--freqs[ransom[i]] >= 0){result = "No"; break;}
\$\endgroup\$