Mutating counts without cleanup
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Build confidence with an intuition-first walkthrough focused on hash map fundamentals.
Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1.
Example 1:
Input: s = "leetcode"
Output: 0
Explanation:
The character 'l' at index 0 is the first character that does not occur at any other index.
Example 2:
Input: s = "loveleetcode"
Output: 2
Example 3:
Input: s = "aabb"
Output: -1
Constraints:
1 <= s.length <= 105s consists of only lowercase English letters.Problem summary: Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map
"leetcode"
"loveleetcode"
"aabb"
sort-characters-by-frequency)first-letter-to-appear-twice)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #387: First Unique Character in a String
class Solution {
public int firstUniqChar(String s) {
int[] cnt = new int[26];
int n = s.length();
for (int i = 0; i < n; ++i) {
++cnt[s.charAt(i) - 'a'];
}
for (int i = 0; i < n; ++i) {
if (cnt[s.charAt(i) - 'a'] == 1) {
return i;
}
}
return -1;
}
}
// Accepted solution for LeetCode #387: First Unique Character in a String
func firstUniqChar(s string) int {
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
}
for i, c := range s {
if cnt[c-'a'] == 1 {
return i
}
}
return -1
}
# Accepted solution for LeetCode #387: First Unique Character in a String
class Solution:
def firstUniqChar(self, s: str) -> int:
cnt = Counter(s)
for i, c in enumerate(s):
if cnt[c] == 1:
return i
return -1
// Accepted solution for LeetCode #387: First Unique Character in a String
struct Solution;
use std::collections::HashMap;
impl Solution {
fn first_uniq_char(s: String) -> i32 {
let mut hm: HashMap<char, i32> = HashMap::new();
for c in s.chars() {
let e = hm.entry(c).or_default();
*e += 1;
}
for (i, c) in s.chars().enumerate() {
if let Some(1) = hm.get(&c) {
return i as i32;
}
}
-1
}
}
#[test]
fn test() {
assert_eq!(Solution::first_uniq_char("leetcode".to_string()), 0);
assert_eq!(Solution::first_uniq_char("loveleetcode".to_string()), 2);
}
// Accepted solution for LeetCode #387: First Unique Character in a String
function firstUniqChar(s: string): number {
const cnt = new Map<string, number>();
for (const c of s) {
cnt.set(c, (cnt.get(c) || 0) + 1);
}
for (let i = 0; i < s.length; ++i) {
if (cnt.get(s[i]) === 1) {
return i;
}
}
return -1;
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan the rest of the array looking for a match. Two nested loops give n × (n−1)/2 comparisons = O(n²). No extra space since we only use loop indices.
One pass through the input, performing O(1) hash map lookups and insertions at each step. The hash map may store up to n entries in the worst case. This is the classic space-for-time tradeoff: O(n) extra memory eliminates an inner loop.
Review these before coding to avoid predictable interview regressions.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.