LeetCode Solution 1. Two Sum
Evolution from Brute Force to Optimal Solution
Problem Description
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]Solution 1: Brute Force
Approach
The most intuitive method is to use two nested loops to check all possible pairs of numbers.
Code
def twoSum(nums, target):
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
if nums[i] + nums[j] == target:
return [i, j]
return []Complexity Analysis
Time Complexity: O(n²)
- Outer loop runs n times
- For each element, inner loop runs n/2 times on average
- Total: approximately n × n/2 = O(n²)
Space Complexity: O(1)
- Only uses constant variables (i, j), doesn’t scale with input size
Pros and Cons
- ✅ Simple and intuitive, easy to understand and implement
- ✅ No extra space required
- ❌ Low time efficiency, very slow for large arrays
Solution 2: Two-Pass Hash Table
Approach
Use a Hash Table to reduce lookup time from O(n) to O(1).
- First pass: Build a mapping from each number to its index
- Second pass: Check if each number’s complement exists
Code
def twoSum(nums, target):
# First pass: build hash table
hashmap = {}
for i in range(len(nums)):
hashmap[nums[i]] = i
# Second pass: look for complement
for i in range(len(nums)):
complement = target - nums[i]
if complement in hashmap and hashmap[complement] != i:
return [i, hashmap[complement]]
return []Complexity Analysis
Time Complexity: O(n)
- First pass: n insertions, each O(1) = O(n)
- Second pass: n lookups, each O(1) = O(n)
- Total: O(n) + O(n) = O(n)
Space Complexity: O(n)
- Hash table stores at most n key-value pairs
Key Understanding: Why is Hash Table lookup O(1)?
Hash Table uses a hash function to directly calculate the storage location of elements, no need for sequential comparison:
Looking up 7 in hashmap:
1. Calculate hash(7) = some position
2. Directly access that position
3. No need to traverse the entire table!Solution 3: One-Pass Hash Table (Optimal Solution)
Approach
Search while traversing, completing everything in a single loop:
- First check if the current number’s complement is already in the hash table
- If not, add the current number to the hash table
Code
def twoSum(nums, target):
hashmap = {}
for i in range(len(nums)):
complement = target - nums[i]
# Search first
if complement in hashmap:
return [hashmap[complement], i]
# Add later
hashmap[nums[i]] = i
return []Algorithm Process Example
Array: [2, 7, 11, 15], Target: 9
i=0, nums[0]=2:
- complement = 9-2 = 7
- Is 7 in hashmap? No
- Add: hashmap = {2: 0}
i=1, nums[1]=7:
- complement = 9-7 = 2
- Is 2 in hashmap? Yes! At position 0
- Return [0, 1] ✓Complexity Analysis
Time Complexity: O(n)
- Worst case traverses the entire array once
- Lookup and insertion in each iteration are O(1)
Space Complexity: O(n)
- Worst case hash table stores n-1 elements
Why Does This Work?
Key insight: For any solution pair (i, j), when we traverse to the larger index, the smaller index is already in the hash table!
Comparison of Three Solutions
| Solution | Time Complexity | Space Complexity | Pros | Cons |
|---|---|---|---|---|
| Brute Force | O(n²) | O(1) | Simple, space-efficient | Slow |
| Two-Pass | O(n) | O(n) | Fast | Requires two loops |
| One-Pass | O(n) | O(n) | Fastest, concise code | Requires extra space |
Key Takeaways
- Time-Space Tradeoff: We trade O(n) extra space for time efficiency improvement from O(n²) to O(n)
- Power of Hash Table: Reducing lookup operation from O(n) to O(1) is key to many algorithm optimizations
- Levels of Algorithm Optimization:
- Step 1: Implement functionality (brute force)
- Step 2: Optimize time complexity (Hash Table)
- Step 3: Optimize actual execution efficiency (one-pass)
Practice Suggestions
- First implement the brute force solution yourself to ensure understanding of the problem
- Think about how to optimize the lookup process
- Try to manually simulate how the Hash Table works
- Compare actual execution times of different solutions on large datasets
This problem is a classic example for understanding Hash Table applications. Mastering the evolution of these three solutions is very helpful for solving other similar problems!