3Sum Closest

Updated on 12 May, 2025
3Sum Closest header image

Problem Statement

The task is to identify three integers within a given array, nums, such that their cumulative sum is closest to a provided integer, target. The array nums will have a length n, and you are required to return the sum of these three integers. For every provided input, there exists precisely one optimal solution, thus implying that a unique closest sum can always be determined.

Examples

Example 1

Input:

nums = [-1,2,1,-4], target = 1

Output:

2

Explanation:

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Example 2

Input:

nums = [0,0,0], target = 1

Output:

0

Explanation:

The sum that is closest to the target is 0. (0 + 0 + 0 = 0).

Constraints

  • 3 <= nums.length <= 500
  • -1000 <= nums[i] <= 1000
  • -104 <= target <= 104

Approach and Intuition

  1. Sorting the Array:

    • Begin by sorting the array nums. Sorting helps in efficiently finding the required numbers as it allows usage of pointer techniques to decide which direction to move within the array.
  2. Initialize Tracking Variables:

    • Start with closest_sum variable to store the closest sum found relative to the target during the iteration. It is initially set to the sum of the first three numbers of the sorted array.
  3. Using Two Pointers:

    • For each element in nums, treat it as a potential first element of the triplet.
    • Use two additional pointers—start and end—initialized to the next element in the array and the last element, respectively.
  4. Evaluate Sums:

    • Calculate the sum of elements at these three pointers. Compare this sum with the target.
    • If the sum is equal to the target, return this sum immediately as this is the closest possible.
    • If the sum is less than the target, move the start pointer one step to the right to increase the sum.
    • If the sum is greater than the target, move the end pointer one step to the left to reduce the sum.
  5. Update Closest Sum:

    • Keep a check if the absolute difference between the current sum and target is smaller than any previously found. If so, update closest_sum with this current sum.
  6. Iterate and Optimize:

    • Continue the process for each element as the potential first element until the entire array has been considered.
    • The answer after finishing the array traversal will be stored in closest_sum.

Key Considerations:

  • Handling of near elements: The method is particularly efficient for non-distinct elements as well, providing the closest possible sum irrespective of duplicates.
  • Efficiency: This approach ensures that the problem is tackled in O(n^2) time complexity because of the nested structure of checking combinations through pointers.
  • Edge Cases: For arrays where all elements are the same, or when target is minimum or maximum, the same technique applies transparently and efficiently.

Example Walkthroughs:

  • For the input nums = [-1,2,1,-4], target = 1, after sorting and evaluating, we find that the closest sum possible is 2 derived from the combination (-1, 2, 1).
  • For nums = [0,0,0], target = 1, though the nums contain identical elements, the sum calculation of (0 + 0 + 0) = 0 is straightforward and closest to 1.

This approach leverages the sorted property of the array to effectively narrow down potential sums, ensuring that the closest sum to the target is quickly and accurately found.

Solutions

  • C++
  • Java
  • C
  • JavaScript
  • Python
cpp
class Solution {
public:
    int closestThreeSum(vector<int>& numbers, int targetValue) {
        int minDiff = INT_MAX;
        int length = numbers.size();
        sort(numbers.begin(), numbers.end());
        for (int i = 0; i < length && minDiff != 0; ++i) {
            for (int j = i + 1; j < length - 1; ++j) {
                int tgt = targetValue - numbers[i] - numbers[j];
                auto it = lower_bound(numbers.begin() + j + 1, numbers.end(), tgt);
                int higher = it - numbers.begin();
                int lower = higher - 1;
                if (higher < length && abs(tgt - numbers[higher]) < abs(minDiff)) {
                    minDiff = tgt - numbers[higher];
                }
                if (lower > j && abs(tgt - numbers[lower]) < abs(minDiff)) {
                    minDiff = tgt - numbers[lower];
                }
            }
        }
        return targetValue - minDiff;
    }
};

The provided C++ solution is designed to find the sum of three integers from a given list that is closest to a specified target value. Here’s how it operates:

  • First, the given list of numbers is sorted to enable efficient searching.
  • The function approaches the problem by iterating over every possible pair of elements using two nested loops.
  • For each pair, it calculates the difference between the target value and the sum of the pair. This difference is termed tgt.
  • Using the lower_bound function, it searches for the third element in the sorted array that, when added to the already chosen pair, brings the sum closest to the target value.
  • The two potential candidates for the closest value are considered: one directly at or below the tgt and one directly above, ensuring these elements are within the valid range of indices.
  • The algorithm updates minDiff if closer sums are found during iterations.
  • Ultimately, it returns the closest sum by adjusting the target value with the smallest found difference, minDiff.

This method guarantees that the absolute difference between the target value and the closest sum computed is the minimum possible, effectively and efficiently solving the problem through a combination of sorting, iterating, and applying binary search.

java
class Solution {
    public int closestThreeSum(int[] numbers, int targetVal) {
        int minDiff = Integer.MAX_VALUE;
        int length = numbers.length;
        Arrays.sort(numbers);
        for (int i = 0; i < length && minDiff != 0; ++i) {
            for (int j = i + 1; j < length - 1; ++j) {
                int neededValue = targetVal - numbers[i] - numbers[j];
                int resultIndex = Arrays.binarySearch(numbers, j + 1, length - 1, neededValue);
                int high = resultIndex >= 0 ? resultIndex : ~resultIndex, low = high - 1;
                if (
                    high < length && Math.abs(neededValue - numbers[high]) < Math.abs(minDiff)
                ) minDiff = neededValue - numbers[high];
                if (
                    low > j && Math.abs(neededValue - numbers[low]) < Math.abs(minDiff)
                ) minDiff = neededValue - numbers[low];
            }
        }
        return targetVal - minDiff;
    }
}

The Java solution provided aims to find the sum of three integers from a given array that is closest to a specified target value. This approach utilizes a combination of sorting, iteration, and binary search to efficiently determine the closest sum. Below is a summary of how the solution works:

  • First, the array of numbers is sorted to facilitate the use of binary search, which is crucial for maintaining the solution's efficiency.
  • A loop iterates through each number in the array as a potential first element of the triplet. These outer iterations continue as long as a perfect match to the target value is not found (i.e., minDiff is not zero).
  • For each fixed element from the outer loop, a nested loop considers subsequent elements as potential second elements of the triplet.
  • Inside the nested loop, the required third element value is calculated by deducting the sum of the first two elements from the target value.
  • Binary search is utilized to find this third element amongst the remaining portion of the array. This search either locates the exact element or provides the closest higher value if an exact match is not found.
  • The differences between the target value and the combinations of the closest possible triplet sums are compared. The closest sum updates the minimum difference (minDiff) as necessary.
  • The overall closest sum is adjusted by subtracting the minDiff from the target value and returned.

The use of binary search and methodical iteration after sorting primarily ensures that the function runs efficiently, handling larger data sets within a reasonable time frame. Moreover, by calculating potential third elements directly and adjusting with binary search results, the solution avoids unnecessary comprehensive triplet evaluations, optimizing performance further.

c
int compare(const void* x, const void* y) { return (*(int*)x - *(int*)y); }
int findClosestSum(int* arr, int arrSize, int targetValue) {
    int smallestDiff = INT_MAX, length = arrSize;
    qsort(arr, arrSize, sizeof(int), compare);
    for (int i = 0; i < length && smallestDiff != 0; ++i) {
        for (int j = i + 1; j < length - 1; ++j) {
            int needed = targetValue - arr[i] - arr[j];
            int low = j + 1, high = length;
            while (low < high) {
                int mid = low + (high - low) / 2;
                if (arr[mid] <= needed)
                    low = mid + 1;
                else
                    high = mid;
            }
            int upperBound = low, lowerBound = low - 1;
            if (upperBound < length && abs(needed - arr[upperBound]) < abs(smallestDiff))
                smallestDiff = needed - arr[upperBound];
            if (lowerBound > j && abs(needed - arr[lowerBound]) < abs(smallestDiff))
                smallestDiff = needed - arr[lowerBound];
        }
    }
    return targetValue - smallestDiff;
}

The provided solution in C programming language addresses the problem of finding the closest sum of three integers to a target value in a given array. Use the following steps and code structure:

  1. Implement a comparison function to use with qsort. This function helps in sorting the array, which is crucial for efficiently finding the closest sum.
  2. Define the main function findClosestSum which accepts an array, its size, and the target value to find the closest sum.
  3. Initialize a variable to store the smallest difference encountered during the computation (smallestDiff), and set it to INT_MAX initially as a form of maximum possible difference.
  4. Use the qsort function from the C standard library to sort the array. This is where the compare function comes into play to determine the order of elements.
  5. Initiate a nested loop structure to explore combinations of three elements. The outer loop selects the first element, and the inner loop attempts to find the best pair of additional elements to come as close as possible to the desired target.
  6. For each pair of elements selected by the outer and inner loops, compute the required third element (needed) which makes the sum closest to the target.
  7. Perform a binary search (using a while loop) to find the closest element in the array that can match or approximate the needed value.
  8. Check bounds to ensure selected indices are valid and compare the differences with the previously smallest difference. If a closer match is found, update smallestDiff.
  9. After all combinations are tested, compute the closest sum by adjusting the target value by the smallest difference found, which gives the closest possible result.
  10. Return the calculated closest sum.

The function effectively reduces the problem space using sorting and binary search to handle the solution in a more optimized manner compared to a brute-force approach. This leads to a more efficient algorithm, especially critical when dealing with large arrays. It handles edge cases such as minimal array size and ensures that the indices are within valid bounds during the search and comparison processes.

js
var closestSum = function(nums, target) {
    let smallestDifference = Number.MAX_SAFE_INTEGER,
        numLength = nums.length;
    nums.sort((x, y) => x - y);
    for (let indexI = 0; indexI < numLength && smallestDifference != 0; ++indexI) {
        for (let indexJ = indexI + 1; indexJ < numLength - 1; ++indexJ) {
            let targetDiff = target - nums[indexI] - nums[indexJ];
            let low = indexJ + 1,
                high = numLength;
            while (low < high) {
                let middle = Math.floor(low + (high - low) / 2);
                if (nums[middle] <= targetDiff) low = middle + 1;
                else high = middle;
            }
            let highIndex = low,
                lowIndex = low - 1;
            if (
                highIndex < numLength &&
                Math.abs(targetDiff - nums[highIndex]) < Math.abs(smallestDifference)
            )
                smallestDifference = targetDiff - nums[highIndex];
            if (
                lowIndex > indexJ &&
                Math.abs(targetDiff - nums[lowIndex]) < Math.abs(smallestDifference)
            )
                smallestDifference = targetDiff - nums[lowIndex];
        }
    }
    return target - smallestDifference;
};

The given JavaScript code snippet provides a solution for finding a triplet in an array such that the sum of the triplet is closest to a given target number. The algorithm uses a two-pointer technique within a sorted version of the input array to efficiently find the closest sum.

Here's a concise explanation of how the code operates:

  • The function closestSum accepts nums (an array of integers) and target (an integer).
  • An initial variable, smallestDifference, is set to the largest safe integer value to keep track of the smallest difference found between the triplet sum and the target.
  • The array nums is then sorted.
  • The function uses two nested loops where the outer loop selects the first element of the triplet, and the inner loop tries to find the best complementing pair using a binary search.
  • During each iteration of the inner loop, the code calculates targetDiff as the difference between the target and the sum of the current fixed elements from the outer loops.
  • The binary search (using variables low, high, middle) adjusts its bounds to determine if a closer sum to target can be achieved by modifying the final element of the current triplet.
  • After the binary search, adjustments to smallestDifference are made based on comparing the absolute differences, updating it if a closer sum is found.
  • Finally, the function returns target - smallestDifference, delivering the value of the closest sum.

Ensure understanding of sorting, binary search, and two-pointer technique for maximum comprehension and efficacy in utilizing or adapting this code snippet.

python
class Solution:
    def closestThreeSum(self, numbers: List[int], goal: int) -> int:
        smallest_diff = float("inf")
        numbers.sort()
        for index1 in range(len(numbers)):
            for index2 in range(index1 + 1, len(numbers)):
                needed = goal - numbers[index1] - numbers[index2]
                upper_bound = bisect_right(numbers, needed, index2 + 1)
                lower_bound = upper_bound - 1
                if upper_bound < len(numbers) and abs(needed - numbers[upper_bound]) < abs(smallest_diff):
                    smallest_diff = needed - numbers[upper_bound]
                if lower_bound > index2 and abs(needed - numbers[lower_bound]) < abs(smallest_diff):
                    smallest_diff = needed - numbers[lower_bound]
            if smallest_diff == 0:
                break
        return goal - smallest_diff

The solution to the "3Sum Closest" problem involves finding three integers in an array such that their sum is closest to a given target number (goal). Here's a breakdown of how the solution works using Python:

  1. Initialize smallest_diff to infinity, which will hold the smallest difference encountered between the goal and the sum of any three numbers.
  2. Sort the list of numbers to facilitate ordered operations and efficient searches.
  3. Use a double loop to iterate through each pair of numbers in the sorted list.
  4. Calculate the difference (needed) between the goal and the current pair of numbers. This helps identify what third number, when added to the current pair, would come close to the goal.
  5. Utilize binary search via bisect_right to quickly find the closest numbers higher (upper_bound) and lower (lower_bound) than the needed value in the remaining part of the list.
  6. Check if the calculated upper and lower bounds improve the closest difference to the goal. Update smallest_diff accordingly.
  7. If at any point the exact target sum is found (smallest_diff equals 0), exit early for efficiency.
  8. After iterating through all pairs, return the sum closest to the goal by adjusting the goal by the smallest_diff.

This approach ensures that the closest possible sum to the target is found efficiently, leveraging sorted order and binary search, allowing for performance optimization particularly for larger lists.

Comments

No comments yet.