Finding Two Numbers in an Array that Sum to a Given Value?

Author: neptune | 14th-Jun-2024
#Algorithms

Given an array `Arr` of `N` positive integers and a target sum `X`, the task is to determine if there exist two distinct elements in `Arr` whose sum is exactly `X`. This problem can be approached using various techniques, each with its own time and space complexities. Below, we explore five different approaches along with their explanations, time complexities, and space complexities. Additionally, Python and Java implementations are provided for each approach.

1. Two Sum using Naive Approach

Explanation

The naive approach involves using two nested loops to check all possible pairs in the array. For each pair, we check if their sum equals `X`.


Time Complexity

- Time Complexity: O(N^2)

- Space Complexity: O(1)


Python Code

 def two_sum_naive(arr, X):

    N = len(arr)

    for i in range(N):

        for j in range(i + 1, N):

            if arr[i] + arr[j] == X:

                return True

    return False



Java Code

    public class TwoSumNaive {

        public static boolean twoSumNaive(int[] arr, int X) {

            int N = arr.length;

            for (int i = 0; i < N; i++) {

                for (int j = i + 1; j < N; j++) {

                    if (arr[i] + arr[j] == X) {

                        return true;

                    }

                }

            }

            return false;

        }

    }



2. Two Sum using Sorting and Two-Pointers Technique

Explanation

First, sort the array. Then, use two pointers: one starting from the beginning (left) and the other from the end (right). If the sum of the elements at these pointers is greater than `X`, move the right pointer leftwards to decrease the sum. If the sum is less, move the left pointer rightwards to increase the sum.


Time Complexity

- Time Complexity: O(N log N) due to sorting + O(N) for the two-pointer traversal.

- Space Complexity: O(1)


Python Code

    def two_sum_two_pointers(arr, X):

        arr.sort()

        left, right = 0, len(arr) - 1

        while left < right:

            current_sum = arr[left] + arr[right]

            if current_sum == X:

                return True

            elif current_sum < X:

                left += 1

            else:

                right -= 1

        return False



Java Code

    import java.util.Arrays;


    public class TwoSumTwoPointers {

        public static boolean twoSumTwoPointers(int[] arr, int X) {

            Arrays.sort(arr);

            int left = 0, right = arr.length - 1;

            while (left < right) {

                int currentSum = arr[left] + arr[right];

                if (currentSum == X) {

                    return true;

                } else if (currentSum < X) {

                    left++;

                } else {

                    right--;

                }

            }

            return false;

        }

    }


3. Two Sum using Binary Search

Explanation

Sort the array. For each element in the array, perform a binary search for `X - arr[i]` in the remaining part of the array.


Time Complexity

- Time Complexity: O(N log N) due to sorting + O(N log N) for binary searches.

- Space Complexity: O(1)

Python Code

    import bisect


    def two_sum_binary_search(arr, X):

        arr.sort()

        for i in range(len(arr)):

            target = X - arr[i]

            j = bisect.bisect_left(arr, target, i + 1)

            if j < len(arr) and arr[j] == target:

                return True

        return False



Java Code

    import java.util.Arrays;


    public class TwoSumBinarySearch {

        public static boolean twoSumBinarySearch(int[] arr, int X) {

            Arrays.sort(arr);

            for (int i = 0; i < arr.length; i++) {

                int target = X - arr[i];

                int j = Arrays.binarySearch(arr, i + 1, arr.length, target);

                if (j > i) {

                    return true;

                }

            }

            return false;

        }

    }



4. Two Sum using Hashing

Explanation

Use a hash set to store elements of the array. For each element, check if `X - arr[i]` is already in the set. If found, the pair exists.


Time Complexity

- Time Complexity: O(N)

- Space Complexity: O(N)

Python Code

    def two_sum_hashing(arr, X):

        seen = set()

        for num in arr:

            if X - num in seen:

                return True

            seen.add(num)

        return False


Java Code

    import java.util.HashSet;


    public class TwoSumHashing {

        public static boolean twoSumHashing(int[] arr, int X) {

            HashSet<Integer> seen = new HashSet<>();

            for (int num : arr) {

                if (seen.contains(X - num)) {

                    return true;

                }

                seen.add(num);

            }

            return false;

        }

    }



5. Two Sum using Remainders

Explanation

Count elements based on their remainders when divided by `X`. Check for pairs of remainders that sum to `X`.


Time Complexity

- Time Complexity: O(N)

- Space Complexity: O(X)


Python Code

    def two_sum_remainders(arr, X):

        remainder_counts = [0X

        for num in arr:

            remainder_counts[num % X] += 1

       

        if remainder_counts[0] > 1:

            return True

       

        for i in range(1, X // 2 + 1):

            if i != X - i:

                if remainder_counts[i] > 0 and remainder_counts[X - i] > 0:

                    return True

            else:

                if remainder_counts[i] > 1:

                    return True

       

        return False




Java Code

    public class TwoSumRemainders {

        public static boolean twoSumRemainders(int[] arr, int X) {

            int[] remainderCounts = new int[X];

            for (int num : arr) {

                remainderCounts[num % X]++;

            }


            if (remainderCounts[0] > 1) {

                return true;

            }


            for (int i = 1; i <= X / 2; i++) {

                if (i != X - i) {

                    if (remainderCounts[i] > 0 && remainderCounts[X - i] > 0) {

                        return true;

                    }

                } else {

                    if (remainderCounts[i] > 1) {

                        return true;

                    }

                }

            }


            return false;

        }

    }




These five approaches provide different ways to solve the problem of finding two numbers in an array that sum to a given value `X`. Each method has its advantages and trade-offs in terms of time and space complexity. Depending on the size of the array and the constraints, one approach may be more suitable than the others.




Related Blogs
Top 8 Algorithms every programmer should Know !!!
Author: neptune | 21st-Apr-2023
#Algorithms
The top 8 algorithms for programmers include sorting, searching, graph, dynamic programming, greedy, divide and conquer, backtracking, and randomized...

View More