Problem overview
The method findTheDifference(String s, String t) receives two strings of lowercase letters. The string t is s shuffled, with exactly one extra letter inserted somewhere. The method returns that extra letter as a char. The length of s is between 0 and 1000, and t is always one character longer.
For s = "abcd" and t = "abcde" the answer is 'e'. For s = "" and t = "y" the answer is 'y', since the only letter of t is the added one.
Approach: a letter is extra if t has more copies of it
Shuffling does not change how many times each letter occurs. So t has the same letter counts as s, except that one letter has one more copy. That letter is the answer, and it is the only letter whose count differs between the two strings.
The brute-force way to use this: for every character of t, count how often it occurs in s, count how often it occurs in t, and compare. The first character with different counts is the extra one. The letters do not need to be found in any order, because only one letter can differ.
The price is repeated work. If t has n characters, each count walks a whole string, and it happens twice for each character, so the total is about 2 * n * n steps, which is O(n²). With strings of up to 1001 characters that is around two million steps, which is fine here, but the same letter is counted again every time it appears. Later lessons on this problem remove that repetition with a hash map and with XOR.
Here is s = "abcd", t = "abcde". For 'a', 'b', 'c' and 'd' the counts are 1 in both strings, so the loop moves on. For 'e' the count in s is 0 and in t is 1, so 'e' is returned.
Step by step
- Write a helper,
static int countChar(String s, char c), above the main method. It will answer "how many times doescoccur ins?". It isstaticbecause it doesn't need any object state, and the main method will call it twice per letter. - Start a counter,
count, at 0. - Loop over the characters of
susings.toCharArray()and acharvariable namedch. AStringcan't be used directly in a for-each loop, so the array form is the simplest way. - Compare each character to
cwithch == c. Forcharvalues,==compares the letters themselves, which is what you want. - Add one to
counton each match. - Return
countafter the loop. - In
findTheDifference, loop over the characters oft. The extra letter is int, so every candidate is there. - Compare the two counts with
countChar(s, i) != countChar(t, i). A difference meansiis the added letter. - Return that letter, and add a final
return ' '. Java requires a return on every path through the method, so the compiler needs one after the loop. By the problem's guarantees the loop always returns before reaching it.
The solution in Java
class Solution {
static int countChar(String s, char c) {
int count = 0;
for (char ch : s.toCharArray()) {
if (ch == c) {
count++;
}
}
return count;
}
public char findTheDifference(String s, String t) {
for (char i : t.toCharArray()) {
if (countChar(s, i) != countChar(t, i)) {
return i;
}
}
return ' ';
}
}
The Java details worth a look:
- No built-in count.
Stringhas no method that counts a single character, so the helper does it with a loop. toCharArray()copies the string's letters into a newchar[]. The string itself is immutable and stays unchanged.- Returning a
charfrom a loop variable. The loop variableihas typechar, soreturn i;matches the method's return type without any cast. The nameiis a character here, not an index. - The final
return ' 'is only there for the compiler. It is never reached for valid input.
Complexity
Time: O(n²), where n is the length of t. The outer loop runs at most n times, and each pass calls countChar twice, each call walking a string of about n characters.
Space: O(n) in this form. Each toCharArray() call allocates a copy of the string, though only one copy is alive at a time and the garbage collector reclaims it. Apart from those short-lived copies, the method keeps a few variables.
Edge cases and common mistakes
- An empty
s. Withs = ""andt = "y",countChar("", 'y')is 0 andcountChar("y", 'y')is 1, so'y'is returned. - The extra letter is a repeat. With
s = "aa"andt = "aaa"the answer is'a'. A check like "is this letter missing froms?" fails here, since'a'is ins. Comparing counts handles it: 2 against 3. - Looping over
sinstead oft. The extra letter is not insunless it is a repeat, so looping overscan miss it. - Counting only in one string. The comparison needs both counts, because a letter that occurs many times in both strings is not the answer.
- Using
Stringinstead ofcharin the helper. Comparing acharwith==works. If you moved toStringvalues, you would have to switch toequals.
Testing
"abcd","abcde"gives'e'."","y"gives'y'."aa","aaa"gives'a'."abcd","dbeca"gives'e'.
