3Sum Closest – 16. LeetCode


The LeetCode problem “3Sum Closest” asks us to find three numbers in an array that sum up to a value closest to a given target. For example, given an array nums = [-1, 2, 1, -4] and target 1, the three numbers closest to the target are [-1, 2, 1], which sum up to 2.


Algorithm and Data Structure Choice

Chosen Algorithm: Sorting and Two-Pointer Technique


The algorithm follows the two-pointer pattern on a sorted array, which is efficient for problems involving finding specific sums in pairs or triplets.

1. Combination of Elements with a Target Sum: The problem asks to find a triplet sum that’s closest to a target. This often suggests a two-pointer approach, especially in sorted arrays.

2. Minimizing the Difference: If the goal involves finding the closest match rather than an exact match, this method allows quick adjustments to bring the sum closer to the target.

3. Handling Multiple Elements: This pattern is useful for problems where multiple elements need to be selected and their sums compared or optimized.


This approach falls under sorted array two-pointer patterns that are frequently applied in problems where pairs or triplets need to reach a certain sum or are constrained in a particular order. Sorting simplifies the process, allowing us to make targeted adjustments instead of checking every combination.

Time Complexity: O(n^2), where n is the number of elements in the array. This is because we sort the array O(n \log n) and then use two pointers within a loop O(n^2).

Space Complexity: O(1), since we only use a few additional variables for tracking the closest sum (ignoring the input array sorting in-place).


High-Level Algorithm Steps

1. Sort the Array: Sort the array to allow for two-pointer adjustments.

2. Initialize Closest Sum: Set an initial closest sum with a large value.

3. Iterate with Fixed Element: For each element in the array (as the first element of the triplet):

• Use two pointers (left and right) to find the other two elements.

4. Calculate and Compare: For each triplet formed by the fixed element and two pointers:

• Calculate the sum.

• If the sum is closer to the target than the current closest, update the closest sum.

5. Adjust Pointers: Move pointers based on the comparison of the sum to the target.

6. Return the Closest Sum: After looping through all elements, return the closest sum.

import java.util.Arrays;

public class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums); // Sort the array for two-pointer approach
int closestSum = Integer.MAX_VALUE / 2; // Initialize closest sum with a large value

for (int i = 0; i < nums.length - 2; i++) { // Fix the first element
int left = i + 1, right = nums.length - 1; // Set two pointers

while (left < right) { // While pointers don't overlap
int currentSum = nums[i] + nums[left] + nums[right]; // Calculate triplet sum

// Check if this sum is closer to target than the closestSum found so far
if (Math.abs(target - currentSum) < Math.abs(target - closestSum)) {
closestSum = currentSum; // Update closestSum if it's closer
}

// Adjust pointers based on comparison with target
if (currentSum < target) {
left++; // Move left pointer right to increase sum
} else if (currentSum > target) {
right--; // Move right pointer left to decrease sum
} else {
return currentSum; // Exact match found
}
}
}
return closestSum; // Return the closest sum found
}
}


Line-by-Line Explanation

  1. Sorting the Array
Arrays.sort(nums);


• Sorting makes it possible to use the two-pointer approach effectively, allowing us to control the sum by moving pointers.

2. Initialize Closest Sum

 int closestSum = Integer.MAX_VALUE / 2;


• We initialize closestSum with a large value to ensure that the first calculated sum will replace it.

3. Loop to Fix the First Element

for (int i = 0; i < nums.length - 2; i++) {

• We loop through each element, treating it as the fixed first element of our triplet.

• We stop at nums.length – 2 to leave space for the other two elements in the triplet.

4. Set Two Pointers

int left = i + 1, right = nums.length - 1;


• We set left to the element immediately after i and right to the last element, enabling us to explore all valid triplets with the fixed element.

5. While Loop to Calculate and Compare Sums

while (left < right) {
int currentSum = nums[i] + nums[left] + nums[right];


• As long as left and right pointers don’t meet, calculate the sum of the three numbers (nums[i], nums[left], and nums[right]).

6, Update Closest Sum if Closer to Target:

if (Math.abs(target - currentSum) < Math.abs(target - closestSum)) {
closestSum = currentSum;
}


• If the current sum is closer to the target than closestSum, we update closestSum to the current sum.

7. Adjust The Pointers

if (currentSum < target) {
left++;
} else if (currentSum > target) {
right--;
} else {
return currentSum;
}

• If currentSum is less than the target, we move left to the right to increase the sum.

• If currentSum is greater than the target, we move right to the left to decrease the sum.

• If currentSum exactly equals the target, we return it immediately as it’s the best possible match.

8, Return the Closest Sum

return closestSum;


• After checking all combinations, closestSum will hold the sum closest to the target, so we return it.


Why This Code Was Coded This Way

Efficiency: The sorted two-pointer technique avoids unnecessary computations by focusing only on valid combinations and making targeted adjustments.

Clarity: The separation of concerns (sorting, initializing, and updating pointers) keeps the code clean and easy to follow.

Scalability: This approach is optimal for larger arrays due to the O(n^2) complexity, making it scalable compared to brute-force approaches.

The two-pointer technique combined with sorting provides a systematic and efficient way to find the sum closest to the target in a clean and understandable solution.

Leave a Reply

Your email address will not be published. Required fields are marked *