Skip to content

Commit 286e49b

Browse files
committed
Feat: Add FourSumProblem and JUnit Test
1 parent 213fd5a commit 286e49b

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.thealgorithms.misc;
2+
import java.util.*;
3+
4+
public class FourSumProblem {
5+
6+
/**
7+
* The function "fourSumProblem" takes an array of integers and a target integer as input, and returns a list
8+
* of unique quadruplets (four elements) from the array that sum up to the target value.
9+
* It avoids duplicate quadruplets by sorting the array and skipping repeated numbers.
10+
* The implementation uses a two-pointer approach to efficiently find the quadruplets.
11+
*
12+
* @param arr An array of integers.
13+
* @param target The target sum that the four integers in each quadruplet should add up to.
14+
* @return A list of lists, where each inner list contains four integers that sum up to the target value.
15+
* @author saivardhan (https://github.com/saivardhan15)
16+
*/
17+
18+
public static List<List<Integer>> fourSumProblem(int[] arr, int target) {
19+
List<List<Integer>> ans = new ArrayList<>();
20+
if (arr.length < 4) {
21+
return ans;
22+
}
23+
// Sort the array to make it easier to detect duplicates
24+
Arrays.sort(arr);
25+
26+
// Loop over the first two elements
27+
for (int i = 0; i < arr.length - 3; i++) {
28+
if (i > 0 && arr[i] == arr[i - 1]) { // Skip duplicate numbers for 'i'
29+
continue;
30+
}
31+
for (int j = i + 1; j < arr.length - 2; j++) {
32+
if (j > i + 1 && arr[j] == arr[j - 1]) { // Skip duplicate numbers for 'j'
33+
continue;
34+
}
35+
36+
// Two-pointer technique for the remaining two elements
37+
int left = j + 1;
38+
int right = arr.length - 1;
39+
while (left < right) {
40+
int sum = arr[i] + arr[j] + arr[left] + arr[right];
41+
if (sum == target) {
42+
ans.add(Arrays.asList(arr[i], arr[j], arr[left], arr[right]));
43+
while (left < right && arr[left] == arr[left + 1]) left++; // Skip duplicates for 'left'
44+
while (left < right && arr[right] == arr[right - 1]) right--; // Skip duplicates for 'right'
45+
left++;
46+
right--;
47+
} else if (sum < target) {
48+
left++;
49+
} else {
50+
right--;
51+
}
52+
}
53+
}
54+
}
55+
return ans;
56+
}
57+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.thealgorithms.misc;
2+
import static org.junit.jupiter.api.Assertions.*;
3+
4+
import java.util.Arrays;
5+
import java.util.List;
6+
import org.junit.jupiter.api.Test;
7+
8+
public class FourSumProblemTest {
9+
@Test
10+
public void testEmptyArray() {
11+
int[] arr = {};
12+
int target = 10;
13+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
14+
assertTrue(result.isEmpty(), "Expected no quadruplets for an empty array");
15+
}
16+
17+
@Test
18+
public void testLessThanFourElements() {
19+
int[] arr = {1, 2, 3};
20+
int target = 6;
21+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
22+
assertTrue(result.isEmpty(), "Expected no quadruplets when array has less than 4 elements");
23+
}
24+
25+
@Test
26+
public void testNoValidQuadruplet() {
27+
int[] arr = {1, 2, 3, 4, 5};
28+
int target = 100;
29+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
30+
assertTrue(result.isEmpty(), "Expected no quadruplets when no combination matches the target");
31+
}
32+
33+
@Test
34+
public void testValidQuadruplet() {
35+
int[] arr = {1, 0, -1, 0, -2, 2};
36+
int target = 0;
37+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
38+
39+
List<List<Integer>> expected = Arrays.asList(Arrays.asList(-2, -1, 1, 2), Arrays.asList(-2, 0, 0, 2), Arrays.asList(-1, 0, 0, 1));
40+
assertEquals(expected.size(), result.size(), "Expected 3 valid quadruplets");
41+
assertTrue(result.containsAll(expected), "The result should contain all expected quadruplets");
42+
}
43+
44+
@Test
45+
public void testWithDuplicates() {
46+
int[] arr = {2, 2, 2, 2, 2};
47+
int target = 8;
48+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
49+
50+
List<List<Integer>> expected = Arrays.asList(Arrays.asList(2, 2, 2, 2));
51+
assertEquals(expected.size(), result.size(), "Expected 1 valid quadruplet for repeated numbers");
52+
assertTrue(result.containsAll(expected), "The result should contain the quadruplet [2, 2, 2, 2]");
53+
}
54+
55+
@Test
56+
public void testNegativeNumbers() {
57+
int[] arr = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
58+
int target = 0;
59+
List<List<Integer>> result = FourSumProblem.fourSumProblem(arr, target);
60+
61+
List<List<Integer>> expected = Arrays.asList(Arrays.asList(-5, -4, 4, 5), Arrays.asList(-5, -3, 3, 5), Arrays.asList(-5, -2, 2, 5), Arrays.asList(-5, -2, 3, 4), Arrays.asList(-5, -1, 1, 5), Arrays.asList(-5, -1, 2, 4), Arrays.asList(-5, 0, 1, 4), Arrays.asList(-5, 0, 2, 3),
62+
Arrays.asList(-4, -3, 2, 5), Arrays.asList(-4, -3, 3, 4), Arrays.asList(-4, -2, 1, 5), Arrays.asList(-4, -2, 2, 4), Arrays.asList(-4, -1, 0, 5), Arrays.asList(-4, -1, 1, 4), Arrays.asList(-4, -1, 2, 3), Arrays.asList(-4, 0, 1, 3), Arrays.asList(-3, -2, 0, 5), Arrays.asList(-3, -2, 1, 4),
63+
Arrays.asList(-3, -2, 2, 3), Arrays.asList(-3, -1, 0, 4), Arrays.asList(-3, -1, 1, 3), Arrays.asList(-3, 0, 1, 2), Arrays.asList(-2, -1, 0, 3), Arrays.asList(-2, -1, 1, 2));
64+
65+
assertEquals(expected.size(), result.size(), "Expected 24 valid quadruplets for negative and positive numbers");
66+
assertTrue(result.containsAll(expected), "The result should contain all expected quadruplets");
67+
}
68+
}

0 commit comments

Comments
 (0)