This code is an implementation of a function closest3Sum
that returns the sum of three numbers in an array that is closest to a given target value. The function leverages a combination of sorting and the two-pointer technique to efficiently find the closest sum. Let’s break it down step by step.
static int closest3Sum(int[] arr, int target) {
// Sort the array to apply the two-pointer technique
Arrays.sort(arr);
// Initialize variables to track the closest sum and the minimum difference
int closestSum = Integer.MIN_VALUE;
int minDiff = Integer.MAX_VALUE;
// Outer loop to iterate over each element in the array (up to arr.length-2)
for (int i = 0; i < arr.length - 2; i++) {
// Set up two pointers: one at i+1 (left) and one at the last element (right)
int left = i + 1;
int right = arr.length - 1;
// While left pointer is less than right pointer, check possible sums
while (left < right) {
// Calculate the current sum of the triplet
int sum = arr[i] + arr[left] + arr[right];
// Calculate the absolute difference between the current sum and the target
int diff = Math.abs(sum - target);
// If the current difference is smaller, or if it's the same but the sum is larger
// (to prefer a larger sum when distances are equal), update closestSum and minDiff
if (diff < minDiff || (diff == minDiff && sum > closestSum)) {
closestSum = sum;
minDiff = diff;
}
// If the current sum is less than the target, increment the left pointer to increase the sum
if (sum < target) {
left++;
}
// If the current sum is greater than the target, decrement the right pointer to decrease the sum
else {
right--;
}
}
}
// Return the closest sum found
return closestSum;
}
-
Sorting the Array:
Arrays.sort(arr);
- First, the array
arr
is sorted in ascending order. Sorting is necessary because it enables the two-pointer approach to efficiently narrow down possible sums.
- First, the array
-
Initial Variables:
int closestSum = Integer.MIN_VALUE; int minDiff = Integer.MAX_VALUE;
closestSum
is initialized to the smallest possible integer value (Integer.MIN_VALUE
) to ensure that any valid sum will be larger initially.minDiff
is initialized to the largest possible integer value (Integer.MAX_VALUE
) to ensure that any valid difference will be smaller initially.
-
Outer Loop:
for (int i = 0; i < arr.length - 2; i++) {
- This loop iterates over each element in the array (
arr[i]
) as the first element of the triplet. Since we are looking for triplets, the loop stops atarr.length - 2
to ensure there are at least two more elements available for the triplet.
- This loop iterates over each element in the array (
-
Setting up Two Pointers:
int left = i + 1; int right = arr.length - 1;
- For each
i
, two pointers are initialized:left
is set to the element right afteri
(i + 1
).right
is set to the last element of the array (arr.length - 1
).
- These two pointers help form the other two elements of the triplet (
arr[left]
andarr[right]
).
- For each
-
Inner While Loop:
while (left < right) { int sum = arr[i] + arr[left] + arr[right];
- The while loop continues as long as
left
is less thanright
. - The sum of the triplet
arr[i] + arr[left] + arr[right]
is calculated.
- The while loop continues as long as
-
Calculating the Difference:
int diff = Math.abs(sum - target);
diff
stores the absolute difference between the current sum and the target value. This helps track how close the current sum is to the target.
-
Updating the Closest Sum:
if (diff < minDiff || (diff == minDiff && sum > closestSum)) { closestSum = sum; minDiff = diff; }
- If the current
diff
is smaller than the previously recordedminDiff
, it means we've found a closer sum to the target, so we updateclosestSum
andminDiff
. - If the
diff
is the same (i.e., the current sum is equally close to the target), we choose the larger sum, which is specified by the condition(diff == minDiff && sum > closestSum)
.
- If the current
-
Adjusting the Pointers:
if (sum < target) { left++; } else { right--; }
- If the sum is less than the target, we want to increase the sum by moving the
left
pointer to the right (left++
). - If the sum is greater than the target, we want to decrease the sum by moving the
right
pointer to the left (right--
).
- If the sum is less than the target, we want to increase the sum by moving the
-
Return the Closest Sum:
return closestSum;
- After completing the loops, the function returns the
closestSum
, which is the sum of the triplet that is closest to the target.
- After completing the loops, the function returns the
Let’s take an example to understand how this works.
-
Input:
arr = [-1, 2, 1, -4]
target = 1
-
Step 1: Sort the array:
[-4, -1, 1, 2]
-
Step 2: Start the outer loop:
- For
i = 0
(arr[i] = -4
):left = 1
,right = 3
- Sum of triplet:
-4 + (-1) + 2 = -3
diff = Math.abs(-3 - 1) = 4
- Update
closestSum = -3
,minDiff = 4
- Since the sum is less than the target, increment
left
.
- For
i = 1
(arr[i] = -1
):left = 2
,right = 3
- Sum of triplet:
-1 + 1 + 2 = 2
diff = Math.abs(2 - 1) = 1
- Update
closestSum = 2
,minDiff = 1
- Since the sum is greater than the target, decrement
right
.
- For
i = 2
(arr[i] = 1
):- The
left
pointer would be beyond theright
pointer, so the loop ends.
- The
- For
-
Step 3: Return
closestSum = 2
.
-
Input:
arr = [1, 1, 1]
target = 3
-
Output: The closest sum is
3
.
- Sorting the array takes
O(n log n)
. - The two-pointer approach for each element takes
O(n)
, wheren
is the length of the array. - Therefore, the overall time complexity is
O(n^2)
.
- The space complexity is
O(1)
because no additional data structures are used apart from the input array.
This code efficiently finds the sum of three elements in an array that is closest to a given target by using sorting and the two-pointer technique, providing an optimal solution with a time complexity of O(n^2)
.