LeetCopilot Logo
LeetCopilot
LeetCode Pattern/Hash Map/Handling Duplicates in Hash Maps: Store First, Last, or All?

Handling Duplicates in Hash Maps: Store First, Last, or All?

LeetCopilot Team
Dec 22, 2025
7 min read
Hash MapDuplicatesEdge CasesInterview Prep
Confused about how to handle duplicate keys? Learn the 4 duplicate strategies and when to use each for different problem types.

You're solving a hash map problem. An element appears twice. What do you do?

Overwrite the old value? Keep the first? Store both?

Handling duplicates correctly is one of the trickiest parts of hash map problems. Get it wrong, and your solution fails on edge cases.

This guide shows you the 4 duplicate strategies and exactly when to use each.

The Four Duplicate Strategies

Strategy 1: Store Last Occurrence

When: Need most recent position, or any valid occurrence

How: Always overwrite

python
index_map = {}
for i, num in enumerate(nums):
    index_map[num] = i  # Overwrites previous

Result: {num: last_index}

Strategy 2: Store First Occurrence

When: Need earliest position, or first unique element

How: Only store if not exists

python
index_map = {}
for i, num in enumerate(nums):
    if num not in index_map:
        index_map[num] = i  # Only store first

Result: {num: first_index}

Strategy 3: Count Occurrences

When: Need frequency, not positions

How: Increment counter

python
from collections import Counter
freq = Counter(nums)

# Or manually
freq = {}
for num in nums:
    freq[num] = freq.get(num, 0) + 1

Result: {num: count}

Strategy 4: Store All Occurrences

When: Need all positions where element appears

How: Append to list

python
from collections import defaultdict

index_map = defaultdict(list)
for i, num in enumerate(nums):
    index_map[num].append(i)

Result: {num: [index1, index2, ...]}

When to Use Each Strategy

Use Last Occurrence When:

Problem type: Two Sum, Contains Duplicate II

Why: Need any valid pair, most recent is fine

Example: Two Sum

python
def twoSum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i  # Store last (overwrites)

Why it works: We check before adding, so we never use the same index twice.

Example: Contains Duplicate II

python
def containsNearbyDuplicate(nums, k):
    index_map = {}
    for i, num in enumerate(nums):
        if num in index_map:
            if i - index_map[num] <= k:
                return True
        index_map[num] = i  # Update to latest
    return False

Why it works: We always want distance from most recent occurrence.

Use First Occurrence When:

Problem type: First Unique Character, Find First Duplicate

Why: Need earliest position

Example: First Unique Character

python
def firstUniqChar(s):
    # Store first index and count
    char_info = {}
    for i, char in enumerate(s):
        if char not in char_info:
            char_info[char] = [i, 1]  # [first_index, count]
        else:
            char_info[char][1] += 1  # Increment count
    
    # Find minimum first index with count 1
    result = float('inf')
    for first_idx, count in char_info.values():
        if count == 1:
            result = min(result, first_idx)
    
    return result if result != float('inf') else -1

Why it works: We need the first unique character, not the last.

Simpler approach (using Counter):

python
from collections import Counter

def firstUniqChar(s):
    freq = Counter(s)
    for i, char in enumerate(s):
        if freq[char] == 1:
            return i
    return -1

Use Count When:

Problem type: Frequency-based problems, Valid Anagram, Top K Frequent

Why: Only care about how many times, not where

Example: Valid Anagram

python
from collections import Counter

def isAnagram(s, t):
    return Counter(s) == Counter(t)

Example: Top K Frequent Elements

python
from collections import Counter
import heapq

def topKFrequent(nums, k):
    freq = Counter(nums)
    return heapq.nlargest(k, freq.keys(), key=freq.get)

Why it works: We only need counts, not positions.

Use All Occurrences When:

Problem type: Find All Anagrams, Intersection of Arrays

Why: Need every position

Example: Find All Anagrams

python
from collections import Counter

def findAnagrams(s, p):
    if len(p) > len(s):
        return []
    
    result = []
    p_count = Counter(p)
    window_count = Counter(s[:len(p)])
    
    if window_count == p_count:
        result.append(0)  # Store all valid indices
    
    for i in range(len(p), len(s)):
        window_count[s[i]] += 1
        left_char = s[i - len(p)]
        window_count[left_char] -= 1
        if window_count[left_char] == 0:
            del window_count[left_char]
        
        if window_count == p_count:
            result.append(i - len(p) + 1)  # Store all
    
    return result

Example: Intersection of Two Arrays II

python
from collections import Counter

def intersect(nums1, nums2):
    count1 = Counter(nums1)
    count2 = Counter(nums2)
    
    result = []
    for num in count1:
        if num in count2:
            # Add min(count1[num], count2[num]) times
            result.extend([num] * min(count1[num], count2[num]))
    
    return result

The Two Sum Duplicate Trap

This is the most common mistake with duplicates.

The Problem

python
nums = [3, 3], target = 6

What should happen?

  • We need two different 3's
  • Should return [0, 1]

Wrong Approach (add before check)

Fails:

python
def twoSum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        seen[num] = i  # Add FIRST
        if target - num in seen:
            return [seen[target - num], i]

# i=0: seen={3:0}, check 6-3=3, found! return [0, 0] ❌

Why it fails: We find the same element at index 0.

Correct Approach (check before add)

Works:

python
def twoSum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        if target - num in seen:  # Check FIRST
            return [seen[target - num], i]
        seen[num] = i  # Add AFTER

# i=0: check 6-3=3 (not found), add {3:0}
# i=1: check 6-3=3 (found!), return [0, 1] ✓

Why it works: At i=1, we check if 3 exists (it does, from i=0), then return [0, 1].

Decision Framework

code
What do you need from duplicates?
├─ Any valid occurrence → Store last (overwrite)
├─ Earliest occurrence → Store first (check if exists)
├─ How many times → Count (increment)
└─ All positions → Store list (append)

Common Mistakes

Mistake 1: Wrong Strategy for Problem

Wrong (storing last when need first):

python
# First unique character with last occurrence
char_map = {}
for i, char in enumerate(s):
    char_map[char] = i  # Overwrites!
# Now we have last occurrence, not first

Mistake 2: Not Checking Before Overwriting

Wrong (Two Sum):

python
seen[num] = i
if target - num in seen:
    return [seen[target - num], i]

Correct:

python
if target - num in seen:
    return [seen[target - num], i]
seen[num] = i

Mistake 3: Using List When Count Suffices

Overkill:

python
# Valid anagram with lists
char_indices = defaultdict(list)
for i, char in enumerate(s):
    char_indices[char].append(i)  # Don't need indices!

Simpler:

python
# Just count
from collections import Counter
return Counter(s) == Counter(t)

Quick Reference

ProblemStrategyCode
Two SumLastseen[num] = i
First Unique CharFirstif num not in seen: seen[num] = i
Valid AnagramCountCounter(s)
Find All AnagramsAllindices[key].append(i)
Contains Duplicate IILastseen[num] = i (update)

Summary

Handling duplicates correctly is about choosing the right strategy.

The 4 strategies:

  1. Last occurrence: Overwrite (Two Sum, distance problems)
  2. First occurrence: Check if exists (first unique, earliest)
  3. Count: Increment (frequency, anagrams)
  4. All occurrences: Append to list (find all, intersection)

The decision:

  • Need any? → Last
  • Need earliest? → First
  • Need how many? → Count
  • Need all? → List

The Two Sum rule: Check before adding (prevents same-index bug)

Next steps:

Handle duplicates correctly, and edge cases become easy.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Tutorials