What does it solve?
Given an array nums and a target, return the indices of the two numbers that add up to it. The brute force checks every pair in O(N²); the hash-map approach does it in one pass.
Key insight: as you scan, for each number x the partner you need is target − x. Keep a hash map of every value seen so far → its index. Before inserting x, look up its complement. A lookup is O(1), so the whole scan is O(N). This "remember and look up" pattern is the core of Contains Duplicate, Group Anagrams, and countless others.
The core idea
seen = {}
for i, x in enumerate(nums):
need = target − x
if need in seen:
return [seen[need], i]
seen[x] = i
Complexity
A single pass over the array. Each element does one O(1) hash lookup and one O(1) insert, versus O(N²) for checking all pairs.
In the worst case every value is stored in the map before the answer is found. Space traded for speed.
Examples & edge cases
Step-by-step table
| Step | i | x = nums[i] | need | in map? | Action | Map after |
|---|
C++ implementation
#include <bits/stdc++.h> using namespace std; // Return indices of the two numbers adding up to target vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> seen; // value -> index for (int i = 0; i < (int)nums.size(); i++) { int need = target - nums[i]; auto it = seen.find(need); if (it != seen.end()) // complement already stored return {it->second, i}; seen[nums[i]] = i; // remember this value } return {}; // no pair sums to target } int main() { vector<int> nums = {2, 7, 11, 15}; auto ans = twoSum(nums, 9); cout << ans[0] << " " << ans[1] << "\n"; // 0 1 return 0; }
My Notes