You see "Two Sum" and immediately write a hash map solution. Then you see "Two Sum II" and... write the same hash map solution.
But wait—the array is sorted. Should you use two pointers instead?
This confusion costs interviews. The decision between hash maps and two pointers is one of the most common choice points in coding interviews, and most candidates don't have a systematic approach.
This guide gives you the decision rule that works every time.
The Simple Decision Rule
Is the array sorted?
├─ Yes → Use two pointers (O(1) space)
└─ No → Do you need original indices?
├─ Yes → Use hash map
└─ No → Sort + two pointersThat's it. Let's see why.
When to Use Two Pointers
Requirements
Use two pointers when:
- ✅ Array is sorted (or can be sorted)
- ✅ Don't need original indices
- ✅ Want O(1) space
- ✅ Finding pairs that meet a condition
The pattern
def twoSum(numbers, target):
"""
Two pointers on sorted array.
Time: O(n)
Space: O(1)
"""
left, right = 0, len(numbers) - 1
while left < right:
current_sum = numbers[left] + numbers[right]
if current_sum == target:
return [left + 1, right + 1] # 1-indexed
elif current_sum < target:
left += 1 # Need larger sum
else:
right -= 1 # Need smaller sum
return []Why it works
Sorted array property:
- If sum is too small → move left pointer right (increase sum)
- If sum is too large → move right pointer left (decrease sum)
This monotonic property makes two pointers possible.
Example: Two Sum II (LeetCode 167)
# Input: numbers = [2, 7, 11, 15], target = 9
# Sorted array - use two pointers
left=0, right=3: 2+15=17 > 9 → right--
left=0, right=2: 2+11=13 > 9 → right--
left=0, right=1: 2+7=9 ✓ → return [1, 2]Complexity: O(n) time, O(1) space
When to Use Hash Map
Requirements
Use hash map when:
- ✅ Array is unsorted
- ✅ Need original indices
- ✅ Can't sort (would lose indices)
- ✅ Can afford O(n) space
The pattern
def twoSum(nums, target):
"""
Hash map on unsorted array.
Time: O(n)
Space: O(n)
"""
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []Why it works
Hash map property:
- Store each number with its index
- For each number, check if complement exists
- O(1) lookup enables O(n) total time
Example: Two Sum (LeetCode 1)
# Input: nums = [2, 7, 11, 15], target = 9
# Unsorted, need indices - use hash map
i=0: num=2, complement=7, not in seen, add {2: 0}
i=1: num=7, complement=2, in seen! return [0, 1]Complexity: O(n) time, O(n) space
Side-by-Side Comparison
Two Sum (unsorted, need indices)
Hash map ✅:
def twoSum(nums, target):
seen = {}
for i, num in enumerate(nums):
if target - num in seen:
return [seen[target - num], i]
seen[num] = i
return []Two pointers ❌ (loses indices):
# Can't use - sorting loses original indices
nums_sorted = sorted(enumerate(nums), key=lambda x: x[1])
# Now indices are wrong!Two Sum II (sorted, 1-indexed)
Two pointers ✅:
def twoSum(numbers, target):
left, right = 0, len(numbers) - 1
while left < right:
s = numbers[left] + numbers[right]
if s == target:
return [left + 1, right + 1]
elif s < target:
left += 1
else:
right -= 1
return []Hash map ❌ (wastes space):
# Works but suboptimal - O(n) space when O(1) possible
seen = {}
for i, num in enumerate(numbers):
if target - num in seen:
return [seen[target - num] + 1, i + 1]
seen[num] = iComparison Table
| Aspect | Hash Map | Two Pointers |
|---|---|---|
| Time | O(n) | O(n) |
| Space | O(n) | O(1) |
| Sorted? | No | Yes |
| Indices? | Yes (original) | No (lost after sort) |
| Best for | Unsorted + need indices | Sorted + O(1) space |
The "Can You Sort?" Decision
Sometimes the array is unsorted, but you don't need original indices.
Question: Can you sort first?
Example: 3Sum (LeetCode 15)
# Find all unique triplets that sum to zero
# Don't need indices - can sort!
def threeSum(nums):
nums.sort() # O(n log n)
result = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i-1]:
continue # Skip duplicates
# Two pointers on remaining array
left, right = i + 1, len(nums) - 1
target = -nums[i]
while left < right:
s = nums[left] + nums[right]
if s == target:
result.append([nums[i], nums[left], nums[right]])
# Skip duplicates
while left < right and nums[left] == nums[left+1]:
left += 1
while left < right and nums[right] == nums[right-1]:
right -= 1
left += 1
right -= 1
elif s < target:
left += 1
else:
right -= 1
return resultWhy sort + two pointers:
- Don't need original indices
- Sorting helps with deduplication
- Two pointers is O(1) space
- Total: O(n²) time, O(1) space
Hash map alternative would be O(n²) time, O(n) space—worse!
Common Mistakes
Mistake 1: Using hash map for sorted array
❌ Suboptimal:
# Two Sum II with hash map
def twoSum(numbers, target):
seen = {}
for i, num in enumerate(numbers):
if target - num in seen:
return [seen[target - num] + 1, i + 1]
seen[num] = i
# O(n) space when O(1) is possible!✅ Optimal:
# Use two pointers
def twoSum(numbers, target):
left, right = 0, len(numbers) - 1
while left < right:
s = numbers[left] + numbers[right]
if s == target:
return [left + 1, right + 1]
elif s < target:
left += 1
else:
right -= 1
# O(1) space!Mistake 2: Sorting when you need indices
❌ Wrong:
# Two Sum (need indices) with sorting
def twoSum(nums, target):
nums.sort() # LOST ORIGINAL INDICES!
# Can't return correct indices now✅ Correct:
# Use hash map to preserve indices
def twoSum(nums, target):
seen = {}
for i, num in enumerate(nums):
if target - num in seen:
return [seen[target - num], i]
seen[num] = iMistake 3: Not recognizing sorted input
❌ Wasteful:
# Problem says "sorted array" but using hash map anyway✅ Efficient:
# Recognize sorted → use two pointersPractice Problems
Use Hash Map (unsorted, need indices)
- Two Sum (#1) - Unsorted, return indices
- 4Sum II (#454) - Multiple arrays, count tuples
Use Two Pointers (sorted)
- Two Sum II (#167) - Sorted array
- 3Sum (#15) - Can sort, don't need indices
- 3Sum Closest (#16) - Can sort
- 4Sum (#18) - Can sort
Tricky (need to decide)
- Container With Most Water (#11) - Two pointers (greedy)
- Trapping Rain Water (#42) - Two pointers or DP
Summary
The decision between hash map and two pointers is systematic.
The rule:
Sorted? → Two pointers (O(1) space)
Unsorted + need indices? → Hash map
Unsorted + don't need indices? → Sort + two pointersHash map:
- ✅ Unsorted array
- ✅ Need original indices
- ✅ Can afford O(n) space
Two pointers:
- ✅ Sorted array
- ✅ Don't need indices
- ✅ Want O(1) space
When in doubt: Check if array is sorted. That's usually the deciding factor.
Next steps:
- Master two sum pattern
- Learn hash map vs other structures
- Study the complete hash map guide
Stop guessing. Use the decision rule.
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
