One would resolve the two sum problem by using two pointers or a hash table algorithm
If the input array is sorted or the output does not require returning array indices, one would use both two-pointers and hash table algorithm
If the input array is not sorted and the output requires returning array indices, one would use the hash table algorithm
Two pointers algorithm uses two indices and walks inward from both ends to reduce the iteration time when searching elements in a sorted linear collection
Hash table has a better performance than other collections in terms of looking up elements
Two Sum problem 1
Given an array of integers a[n]
and an integer number k
as a target sum. Determine whether there is a pair of elements a[i]
and a[j]
that sums exactly to k
Example
Given an array a [1, 3, 7] and k = 8 then the answer is
true
, but given k=5 then the answer isfalse
Given an array a [4, -9, 0, 11, 6, -20, 1, 7] and k = -14 then the answer is
true
, but given k = -15 then the answer isfalse
Approach: Brute force
- Use 2 for-loop to try all pairs in the given array
a
to see if any of them add up tok
import java.util.Arrays;
public class TwoSum_BruteForce {
static boolean bruteForce(int[] a, int k) {
for (int i = 0; i < a.length ; i++) {
for (int j = i+1; j < a.length; j++) {
if (a[i] + a[j] == k) return true;
}
}
return false;
}
public static void main(String[] args) {
int[] a = {1, 3, 7};
System.out.println(bruteForce(a, 8));
System.out.println(bruteForce(a, 5));
int[] b = {4, -9, 0, 11, 6, -20, 1, 7};
System.out.println(bruteForce(b, -14));
System.out.println(bruteForce(b, -15));
}
}
- Output
true
false
true
false
Time complexity: O(n2) as with each element, the algorithm loops through the array which takes O(n) time
Space complexity: O(1)
Approach: Two pointers
Sort the given array
Walk two indices
i
andj
inward from both ends of the array. Whilei
is still less thanj
, calculate the sums
of their corresponding elements. Ifs
equals to the givenk
then returntrue
and exit the algorithm immediately. Ifs
is less thank
, increasesi
by 1, otherwise decreasesj
by 1Finally, return
false
as no pair has a sum equal tok
import java.util.Arrays;
public class TwoSum_TwoPointers {
static boolean twoPointers(int[] a, int k) {
Arrays.sort(a);
int i = 0;
int j = a.length - 1;
while (i < j) {
int sum = a[i] + a[j];
if (sum == k) {
return true;
} else if (sum < k) {
i++;
} else {
j--;
}
}
return false;
}
public static void main(String[] args) {
int[] a = {1, 3, 7};
System.out.println(twoPointers(a, 8));
System.out.println(twoPointers(a, 5));
int[] b = {4, -9, 0, 11, 6, -20, 1, 7};
System.out.println(twoPointers(b, -14));
System.out.println(twoPointers(b, -15));
}
}
- Output
true
false
true
false
Time complexity: O(nlogn) due to the cost of sorting
Space complexity: O(1)
Approach: Hash table
Create a new HashSet
h
Loop through the given array
a
. For each array elementa[i]
, check if existing an elementa[j]
thata[j] = k - a[i]
. If yes returntrue
and exit the algorithm immediately, otherwise adda[i]
intoh
Finally, return
false
as no pair has a sum equal tok
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class TwoSum_HashTable {
static boolean hashTable(int[] a, int k) {
HashSet<Integer> h = new HashSet<>();
for (int i = 0; i < a.length ; i++) {
if (h.contains(k - a[i])) return true;
h.add(a[i]);
}
return false;
}
public static void main(String[] args) {
int[] a = {1, 3, 7};
System.out.println(hashTable(a, 8));
System.out.println(hashTable(a, 5));
int[] b = {4, -9, 0, 11, 6, -20, 1, 7};
System.out.println(hashTable(b, -14));
System.out.println(hashTable(b, -15));
}
}
- Output
true
false
true
false
Time complexity: O(n) as with each element, the algorithm looks up in the hash table which takes O(1) time
Space complexity: O(n) as the algorithm use a hash table size
n
Two Sum problem 2
Given an array of integers nums
and an integer number k
as a target sum. Return indices of the two numbers such that they add up to k
Example
Input: nums = [1, 3, 7], k = 8. Output: [0, 2]
Input: nums = [4, -9, 0, 11, 6, -20, 1, 7], k = -14. Output: [4, 5]
Approach: HashTable
Loops through the array nums
and puts each element value nums[i]
and index i
into a HashMap as key and value
Each time, check if the map contains key k - nums[i]
then return {map.get(k - nums[i]), i}
as the result
public int[] twoSum(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int i=0; i<nums.length; i++) {
if (map.containsKey(k - nums[i])) {
return new int[]{map.get(k - nums[i]), i};
}
map.put(nums[i], i);
}
return null;
}
Time complexity: O(n)
Space complexity: O(n)