18. 4Sum
- Given an array
nums
ofn
integers, return an array of all the unique quadruplets[nums[a], nums[b], nums[c], nums[d]]
such that:0 <= a, b, c, d < n
-
a
,b
,c
, andd
are distinct. nums[a] + nums[b] + nums[c] + nums[d] == target
- You may return the answer in any order.
Example 1
Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [ [ -2,-1,1,2],[-2,0,0,2],[-1,0,0,1 ] ]
Example 2
Input: nums = [2,2,2,2,2], target = 8
Output: [ [ 2,2,2,2 ] ]
Method 1
【O(n³) time | O(1) space】
package Leetcode.TwoPointer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author zhengxingxing
* @date 2025/02/23
*/
public class FourSum {
public static List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
// Check for invalid input
if (nums == null || nums.length < 4) {
return result;
}
// Sort array to use two-pointer technique and handle duplicates
Arrays.sort(nums);
int n = nums.length;
// Fix first number
for (int i = 0; i < n - 3; i++) {
// Skip duplicates for first number
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// Early termination if smallest possible sum is too large
if ((long)nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
// Skip if largest possible sum is too small
if ((long)nums[i] + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
// Fix second number
for (int j = i + 1; j < n - 2; j++) {
// Skip duplicates for second number
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
// Early termination optimizations
if ((long)nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
break;
}
if ((long)nums[i] + nums[j] + nums[n - 2] + nums[n - 1] < target) {
continue;
}
// Use two pointers to find remaining two numbers
int left = j + 1, right = n - 1;
while (left < right) {
long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
// Add valid quadruplet to result
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
// Skip duplicates for third number
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
// Skip duplicates for fourth number
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
left++;
right--;
} else if (sum < target) {
left++; // Sum too small, increase left pointer
} else {
right--; // Sum too large, decrease right pointer
}
}
}
}
return result;
}
public static void main(String[] args) {
// Test Case 1: Standard case with multiple solutions
int[] nums1 = {1, 0, -1, 0, -2, 2};
int target1 = 0;
System.out.println("Test Case 1:");
System.out.println("Input: nums = [1,0,-1,0,-2,2], target = 0");
System.out.println("Output: " + fourSum(nums1, target1));
System.out.println();
// Test Case 2: Array with all same elements
int[] nums2 = {2, 2, 2, 2, 2};
int target2 = 8;
System.out.println("Test Case 2:");
System.out.println("Input: nums = [2,2,2,2,2], target = 8");
System.out.println("Output: " + fourSum(nums2, target2));
System.out.println();
// Test Case 3: Large dataset with positive and negative numbers
int[] nums3 = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
int target3 = 0;
System.out.println("Test Case 3 (Large Dataset):");
System.out.println("Output: " + fourSum(nums3, target3));
}
}
Enjoy Reading This Article?
Here are some more articles you might like to read next: