Problem overview
The method findTheDifference(s, t) receives two strings of lowercase letters. The string t contains every letter of s, shuffled, plus exactly one extra letter somewhere. The method returns that extra letter as a one-character string.
With s = "abcd" and t = "abcde", every letter of s appears once in t, and e has no partner, so the answer is "e". With s = "" and t = "y" there is nothing to pair with, so the answer is "y". The string s can be empty, and t is always exactly one character longer.
Approach: compare counts, letter by letter
The extra letter has to be one of the letters in t, so the search can walk through t and test each letter: "is this the extra one?"
A letter is the extra one exactly when it appears more often in t than in s. Every other letter appears the same number of times in both strings, because t is a shuffle of s plus one more letter. So for each letter of t, count it in s, count it in t, and compare. The first letter whose two counts differ is the answer.
Take s = "aab" and t = "abaa". The letter a appears 2 times in s and 3 times in t, so the very first letter of t already gives the answer "a". With t = "bab" and s = "ab", the letter b is counted 1 time in s and 2 times in t, and the method returns "b".
This is the simplest correct idea, and it is slow: counting a letter walks a whole string, and the method does it for every letter of t. That makes it O(n²). The next lessons on this problem keep the counts in a hash table and then use XOR to reach O(n). This one starts from the version that is easiest to get right.
Step by step
- Write a helper called
countChar(str, ch)on theSolutionclass, abovefindTheDifference. It answers one question, "how many times doeschappear instr?", and the main method asks it twice per letter. - Declare
countwithletand set it to 0. It is the running tally, and it changes, so it can't be aconst. - Loop over
strwithfor...of. Looping over a string withfor...ofgives one character at a time, andconst cis fine because each pass creates a fresh variable. - Check
c === ch. Both are one-character strings, and===compares them without any type conversion. - Increment
countinside theifblock. - Return
countafter the loop, so the helper reports the total only once every character has been checked. - In
findTheDifference, loop overt. The extra letter is guaranteed to be int, so there is no reason to look at the letters ofs. - Compare the two counts. Inside a class, the helper is called with
this.countChar(...). A mismatch means this letter appears more often intthan ins. - Return the letter at once. Exactly one letter has mismatched counts, so there is nothing left to look for.
The solution in JavaScript
class Solution {
countChar(str, ch) {
let count = 0;
for (const c of str) {
if (c === ch) {
count++;
}
}
return count;
}
findTheDifference(s, t) {
for (const i of t) {
if (this.countChar(s, i) !== this.countChar(t, i)) {
return i;
}
}
}
}
Some JavaScript details worth a closer look:
- Methods need
this..countCharis a method of the class, not a free function. WritingcountChar(s, i)withoutthis.looks for a variable of that name and throws aReferenceError. for...ofversusfor...in.for (const c of str)yields the characters.for (const c in str)would yield the indexes, as strings, and the comparisonc === chwould never be true.- No return at the end. A function that finishes without reaching a
returngives backundefined. Here that can't happen for valid input, because one letter always differs, but it is why the method has no final line. - Strings are compared by value.
"a" === "a"istrue, so the helper'sc === chworks for strings with no extra care.
Complexity
Time: O(n²), where n is the length of t. The outer loop visits up to n letters, and for each one countChar walks s and then t, about 2n steps. That is roughly 2n² steps in the worst case, which is O(n²). With the lesson's limit of 1000 letters, this is a few million steps at most, which is fast enough.
Space: O(1). The method keeps a counter and a loop variable, and never builds a new string or array.
Edge cases and common mistakes
- An empty
s. Withs = ""andt = "y",countChar("", "y")is 0 andcountChar("y", "y")is 1, so the method returns"y". - The extra letter is a repeat. With
s = "aab"andt = "abaa", the answer is"a", a letter that is already ins. Checking only "is this letter missing froms?" would find nothing, which is why the lesson compares counts. - Looping over
sinstead oft. If the extra letter is new, it never shows up in the loop, and the method returnsundefined. - Comparing with
==or the wrong operator. The check is!==between two numbers. Writing=by mistake assigns instead of comparing. - Counting only in one string. The comparison needs both counts. A letter that appears twice in
sand twice intis not the extra one.
Testing
s = "abcd",t = "abcde"gives"e".s = "",t = "y"gives"y".s = "aab",t = "abaa"gives"a".s = "ab",t = "bab"gives"b".
