387. First Unique Character in a String
easyAsked at BloombergGiven a string, find the index of the first non-repeating character, or -1 if all repeat. Bloomberg uses this as a hash-map fluency warm-up — they want a two-pass O(n) with a discussion of LinkedHashMap (or ordered Map) as an alternative.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Bloomberg loops.
- Glassdoor (2026-Q1)— Bloomberg SWE phone-screen reports cite First Unique Character as a recurring string + hash-map warm-up.
- Blind (2025-12)— Bloomberg new-grad reports note this as a common Round 1 question.
Problem
Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1.
Constraints
1 <= s.length <= 10^5s consists of only lowercase English letters.
Examples
Example 1
s = "leetcode"0Example 2
s = "loveleetcode"2Example 3
s = "aabb"-1Approaches
1. Two-pass frequency count (optimal)
First pass: count frequency of each char. Second pass: return the index of the first char with count 1.
- Time
- O(n)
- Space
- O(1)
function firstUniqChar(s) {
const count = new Map();
for (const ch of s) {
count.set(ch, (count.get(ch) || 0) + 1);
}
for (let i = 0; i < s.length; i++) {
if (count.get(s[i]) === 1) return i;
}
return -1;
}Tradeoff: The canonical two-pass answer. Space is technically O(1) because the alphabet is bounded (26 lowercase letters). Bloomberg's preferred answer.
2. Ordered map with single pass
JavaScript's Map preserves insertion order. Track count + first-seen index; iterate the map at the end for the smallest index with count 1.
- Time
- O(n)
- Space
- O(1)
function firstUniqCharSingle(s) {
const info = new Map();
for (let i = 0; i < s.length; i++) {
const ch = s[i];
if (info.has(ch)) info.set(ch, { count: info.get(ch).count + 1, idx: info.get(ch).idx });
else info.set(ch, { count: 1, idx: i });
}
let best = -1;
for (const { count, idx } of info.values()) {
if (count === 1 && (best === -1 || idx < best)) best = idx;
}
return best;
}Tradeoff: Single pass through s but more bookkeeping. The two-pass version is clearer and Bloomberg interviewers tend to prefer it.
Bloomberg-specific tips
Bloomberg interviewers like the two-pass solution because it's clean and easy to defend. State 'first pass counts, second pass scans in order for the first count-1 entry' before coding. Mention the LinkedHashMap variant if they probe for alternatives.
Common mistakes
- Returning the character instead of the index.
- Failing to return -1 when no unique character exists.
- Using nested loops — O(n^2) when O(n) is trivial.
Follow-up questions
An interviewer at Bloomberg may pivot to one of these next:
- First Unique Number — same shape but on integers.
- Find the Difference (LC 389) — XOR or frequency.
- Group Anagrams (LC 49) — frequency-as-key pattern.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why is space O(1)?
Because the alphabet is bounded to 26 lowercase letters per the constraints. The map size never exceeds 26 regardless of n.
Stream variant?
Bloomberg sometimes asks 'what if chars stream one at a time and we want the first unique at any moment?' Use an ordered map + sentinel; pop expired uniques from the front.
Free learning resources
Curated free links for this problem.
Practice these live with InterviewChamp.AI
Drill First Unique Character in a String and other Bloomberg interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →