First Non Repeating Character Using Hash in DSA Go - Time & Space Complexity
We want to find how long it takes to find the first character that appears only once in a string using a hash map.
How does the time needed grow as the string gets longer?
Analyze the time complexity of the following code snippet.
func firstNonRepeatingChar(s string) byte {
freq := make(map[byte]int)
for i := 0; i < len(s); i++ {
freq[s[i]]++
}
for i := 0; i < len(s); i++ {
if freq[s[i]] == 1 {
return s[i]
}
}
return 0
}
This code counts how many times each character appears, then finds the first character that appears only once.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Two loops over the string characters.
- How many times: Each loop runs once over all characters, so twice in total.
As the string length grows, the code does two full passes over the characters.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 steps (2 x 10) |
| 100 | About 200 steps (2 x 100) |
| 1000 | About 2000 steps (2 x 1000) |
Pattern observation: The operations grow roughly twice the input size, so the growth is linear.
Time Complexity: O(n)
This means the time needed grows directly in proportion to the string length.
[X] Wrong: "Because there are two loops, the time complexity is O(n²)."
[OK] Correct: The loops run one after another, not inside each other, so their times add up, not multiply.
Understanding how to analyze loops like this helps you explain your code clearly and shows you know how to judge efficiency in real problems.
"What if we used a nested loop to check each character against all others instead of a hash map? How would the time complexity change?"
Practice
Solution
Step 1: Understand the role of hash map
A hash map stores each character as a key and counts how many times it appears in the string.Step 2: Use frequency to find non-repeating character
By checking the counts, we can find the first character with count 1, which is the first non-repeating character.Final Answer:
To count the frequency of each character efficiently -> Option AQuick Check:
Hash map counts characters = frequency count [OK]
- Thinking hash map sorts characters
- Using hash map to reverse string
- Confusing hash map with linked list
Solution
Step 1: Identify correct map key type for characters
In Go, characters from strings are best represented as 'rune' type, so map[rune]int is correct for counting characters.Step 2: Check other options
counts := make(map[string]int) uses string as key which is incorrect for single characters; counts := make(map[int]string) reverses key and value types; counts := make([]int, len(s)) is a slice, not a map.Final Answer:
counts := make(map[rune]int) -> Option DQuick Check:
Use map[rune]int for character counts in Go [OK]
- Using map[string]int for single characters
- Confusing slices with maps
- Using wrong key-value types in map
package main
import "fmt"
func main() {
s := "swiss"
counts := make(map[rune]int)
for _, ch := range s {
counts[ch]++
}
for _, ch := range s {
if counts[ch] == 1 {
fmt.Println(string(ch))
break
}
}
}Solution
Step 1: Count character frequencies in "swiss"
Characters and counts: 's' = 3, 'w' = 1, 'i' = 1.Step 2: Find first character with count 1 in order
Order in string: 's'(3), 'w'(1), 'i'(1), 's'(3), 's'(3). First with count 1 is 'w'.Final Answer:
w -> Option AQuick Check:
First unique char in "swiss" is 'w' [OK]
- Picking 's' which repeats
- Choosing 'i' ignoring order
- Expecting no output
package main
import "fmt"
func main() {
s := "hello"
counts := make(map[rune]int)
for i := 0; i < len(s); i++ {
counts[rune(s[i])] = counts[rune(s[i])] + 1
}
for i := 0; i < len(s); i++ {
if counts[rune(s[i])] == 1 {
fmt.Println(s[i])
break
}
}
}Solution
Step 1: Check how character is printed
Printing s[i] prints a byte as integer, not the character itself.Step 2: Fix printing to convert byte to string
Use fmt.Println(string(s[i])) to print the character properly.Final Answer:
Printing s[i] prints byte, not character -> Option CQuick Check:
Print string(s[i]) to show character, not byte [OK]
- Ignoring printing type mismatch
- Changing map key type unnecessarily
- Not initializing map (already done)
"aabbccdde", which code modification will correctly find the first non-repeating character using a hash map in Go, considering the string may contain Unicode characters?Solution
Step 1: Choose correct map key type for Unicode
Using map[rune]int allows counting Unicode characters correctly, unlike byte which only handles ASCII.Step 2: Use range loop to iterate runes
Using 'for _, ch := range s' iterates over runes, correctly handling multi-byte Unicode characters.Final Answer:
Use map[rune]int and iterate with 'for _, ch := range s' to count frequencies -> Option BQuick Check:
map[rune]int + range loop handles Unicode correctly [OK]
- Using byte keys breaks Unicode characters
- Splitting string incorrectly into substrings
- Using int keys without clear mapping
Ready to prove it?
Pass the test and this pattern moves unknown
