Given a string s
consisting of lowercase English letters, return the first letter to appear twice.
Note:
a
appears twice before another letter b
if the second occurrence of a
is before the second occurrence of b
.s
will contain at least one letter that appears twice.
Example 1:
Input: s = "abccbaacz" Output: "c" Explanation: The letter 'a' appears on the indexes 0, 5 and 6. The letter 'b' appears on the indexes 1 and 4. The letter 'c' appears on the indexes 2, 3 and 7. The letter 'z' appears on the index 8. The letter 'c' is the first letter to appear twice, because out of all the letters the index of its second occurrence is the smallest.
Example 2:
Input: s = "abcdd" Output: "d" Explanation: The only letter that appears twice is 'd' so we return 'd'.
Constraints:
2 <= s.length <= 100
s
consists of lowercase English letters.s
has at least one repeated letter.Given a string s
consisting of lowercase English letters, find the first letter that appears twice in the string. The "first" letter is defined as the letter whose second occurrence has the smallest index in the string.
Two efficient solutions exist: using a hash table (or array) and using bit manipulation.
This approach uses a hash table (or an array of size 26 for lowercase English letters) to store the counts of each character encountered so far. We iterate through the string. For each character:
Time Complexity: O(n), where n is the length of the string. We iterate through the string once. Space Complexity: O(1) (using an array), or O(k) in the worst case if using a hash table where k is the number of unique characters (but it will be at most 26 in this problem).
from collections import Counter
class Solution:
def repeatedCharacter(self, s: str) -> str:
cnt = Counter()
for c in s:
cnt[c] += 1
if cnt[c] == 2:
return c
class Solution {
public char repeatedCharacter(String s) {
int[] cnt = new int[26];
for (char c : s.toCharArray()) {
cnt[c - 'a']++;
if (cnt[c - 'a'] == 2) {
return c;
}
}
return ' '; //Should not reach here as problem statement guarantees a repeated character
}
}
class Solution {
public:
char repeatedCharacter(string s) {
vector<int> count(26, 0);
for (char c : s) {
count[c - 'a']++;
if (count[c - 'a'] == 2) {
return c;
}
}
return ' '; //Should not reach here
}
};
(Other languages like Go, Javascript, TypeScript, Rust etc. would have very similar implementations following the same logic.)
This method is space-efficient, using a single integer mask
to track which characters have appeared. Each bit in the integer represents a character (0-25 for a-z).
mask = 0
.i = c - 'a'
).i
-th bit in mask
is already set (meaning the character has appeared before), return the character.i
-th bit in mask
.Time Complexity: O(n) Space Complexity: O(1) (constant space, regardless of input size)
class Solution:
def repeatedCharacter(self, s: str) -> str:
mask = 0
for c in s:
i = ord(c) - ord('a')
if (mask >> i) & 1:
return c
mask |= 1 << i
class Solution {
public char repeatedCharacter(String s) {
int mask = 0;
for (char c : s.toCharArray()) {
int i = c - 'a';
if ((mask >> i & 1) == 1) {
return c;
}
mask |= 1 << i;
}
return ' '; //Should not reach here
}
}
(Again, other languages would follow similar principles.)
Both solutions achieve linear time complexity, but the bit manipulation approach is slightly more space-efficient because it uses a constant amount of extra space regardless of the input size. The hash table approach's space complexity is technically O(1) in the context of this problem because the alphabet is fixed, but it could grow larger if the character set were different.