Naive: check every pair with two nested loops. This is O(n²).
Optimized: for each element x, check if (target - x) exists in a hash map. Hash lookups are O(1), so total time is O(n).
The hash map trades space for speed. You store n elements but avoid the quadratic loop.