Two Sum
Problem Statement
- Given an array of integers
nums
and an integertarget
, return indices of the two numbers such that they add up to target. - You may not use the same element twice. If multiple solutions exist, return the answer with smallest indices
Note: Sorting elements would change their indices. Since we have to return indices (and not elements), this approach would not work
1. Brute
Time \( = (N-1) + (N-2) + … + 1 = O(N^2) \)
Metric | Complexity |
---|---|
Time | \( O(N^2) \) |
Space | \( O(1) \) |
2. Hashing
Using Hashmap to track elements seen before. While traversing, check if complement exists
Metric | Complexity |
---|---|
Time | \( O(N) \) |
Space | \( O(N)\) … for Hashmap |
C++ code
Variant: Multiple occurences and solutions. Count how many solutions: GFG
Since the same value element can be present at multiple indices and we only have to return total number of pairs, we can maintain a frequency-count map that tracks how how many places one value exists in array
The cases we need to handle are:
-
Picking same value twice to form sum pair
When the target value is twice that of a value present in array, we need number of ways we can select 2 items from total frequency of that value. Let \(a\) be the frequency count of the element
\[ \therefore \text{ways to select } = {^a}{C_2} = a(a-1)/2 \]
Note: If \( a < 2 \) , then zero ways to select as there won’t be any pair formed. At \( a = 1, \space a(a-1)/2 = 0 \) . Thus, that edge-case gets handled. If count < 1, it’s even not even added into frequency map
-
Picking two diffent values to form sum pair
Let \( \space a, b \space \) be the frequencies of the elements that add up to target
\[ \therefore \text{ways to select } = {^a}{C_1} \cdot {^b}{C_1} = a \cdot b \]
Metric | Complexity |
---|---|
Time | \( O(2 \cdot N) \) … Traversing array & frequency map |
Space | \( O(N)\) … for Hashmap |
C++ code
Variant: Input array is sorted, with one solution: LeetCode
1. Binary search
In worst case, we have to go till last pair. So the time taken:
\( = log(n-1) + log(n-2) + … + log(1) \)
\( = log[ (n-1) \ast (n-2) … \ast 1] \)
\( = log[(n-1)!] \approx O(n \cdot logn) \) … refer here
Metric | Complexity |
---|---|
Time | \( O(N \cdot logN) \) |
Space | \( O(1) \) |
C++ code
2. Two-Pointer
At each step, one of the two pointers is moving closer to the other. At worst, they will meet, thereby covering all elements once i.e. \( O(n) \) time
Metric | Complexity |
---|---|
Time | \( O(N) \) |
Space | \( O(1) \) |