There are three approaches to solve this problem - 1) brute force, 2) sort the array and use binary and search, and 3) Using the hashtable.
Please scroll down, if you are only interested in the best approach i.e. approach 3 using hashtables.
The first approach is to use brute force which gives time complexity of O(n^2) and space complexity of O(n). We basically just have to loop through the array and for each number we add it to each of other numbers and see if they sum up to 5. If so, we print out the pair. Here is the code for brute force approach:
classSolution {
publicint[]twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i]+ nums[j]== target) {
returnnewint[]{i, j}; // Return indices }
}
}
returnnewint[]{-1, -1}; // Return invalid pair if no solution }
}
1
2
3
4
5
6
7
classSolution:
deftwoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i +1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
return [-1, -1] # Return invalid pair if no solution
A better way would be to sort the array. This takes O(n log n)
Then for each x in array A, use binary search to look for T-x. This will take O(nlogn).
So, overall search is O(n log n)
arr = {}; //some arraysortedArr = sort(arr);
for (i = 0; i < arr.length- 1; i++) {
x = arr[i];
bool found = binarySearch(sortedArr, T - x); //Search for T-x in sorted Arraryif (found)
print "pair", x, T - x;
}
Problem with above approach is, what if x = T/2, then we will find the element, even though it will find the same element again.
classSolution {
publicint[]twoSum(int[] nums, int target) {
int[][] indexedNums =newint[nums.length][2];
for (int i = 0; i < nums.length; i++) {
indexedNums[i][0]= nums[i]; // Store value indexedNums[i][1]= i; // Store index }
Arrays.sort(indexedNums, (a, b) -> Integer.compare(a[0], b[0])); // Sort by valuefor (int i = 0; i < nums.length; i++) {
int complement = target - indexedNums[i][0];
int idx = binarySearch(indexedNums, i + 1, nums.length- 1, complement);
if (idx !=-1) {
returnnewint[]{indexedNums[i][1], indexedNums[idx][1]};
}
}
returnnewint[]{-1, -1}; // No solution }
privateintbinarySearch(int[][] nums, int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid][0]== target) return mid;
if (nums[mid][0]< target) left = mid + 1;
else right = mid - 1;
}
return-1; // Not found }
}
Assuming array sorted in ascending order. Now we take first and last element, and sum them up. If sum is equal to T, we have found the pair, but if sum is greater than T, we reduce right pointer by 1, or increment left pointer otherwise.
I have already mentioned in problem in the application of hash table here.
The best way would be to insert every element into a hash table (without sorting). This takes O(n) as constant time insertion.
Then for every x, we can just look up its complement, T-x, which is O(1).
Overall it takes will be O(n).
Let arr be the given array.
And T be the given sum
hash = {}
for (i = 0 i < arr.length- 1; i++) {
// key is the element and value is its index. num = arr[i] complement = T - num
if complement in hash and hash[complement]< i:
print("Pair:", i, ",", hash[complement], "has sum", T)
hash[num]= i
}
classSolution {
publicint[]twoSum(int[] nums, int target) {
Map<Integer, Integer> map =new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int compliment = target - nums[i];
if (map.containsKey(compliment)) {
returnnewint[]{map.get(compliment), i};
}
map.put(nums[i], i);
}
returnnewint[]{-1, -1}; // No solution }
}
1
2
3
4
5
6
7
8
9
classSolution:
deftwoSum(self, nums: List[int], target: int) -> List[int]:
index_map: dict[int, int] = {}
for i, num in enumerate(nums):
complement = target - num
if complement in index_map:
return [index_map[complement], i]
index_map[num] = i
return [-1, -1] # No solution