Skip to content

Commit a2dd6ed

Browse files
authored
Merge pull request #628 from harshadunna/harshadunna
Added 3Sum and Dutch National Flag algorithms in Java
2 parents cae208d + 0ee972b commit a2dd6ed

2 files changed

Lines changed: 177 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import java.util.Arrays;
2+
3+
/**
4+
* ## Dutch National Flag Problem (Sort Colors)
5+
*
6+
* This algorithm sorts an array containing only three distinct elements (0, 1, and 2) in-place.
7+
* It's a classic partitioning problem that is solved in a single pass.
8+
*
9+
* ### How it works:
10+
* 1. Use three pointers: `low`, `mid`, and `high`.
11+
* 2. `low` points to the boundary of the '0' section.
12+
* 3. `high` points to the boundary of the '2' section.
13+
* 4. `mid` is the current element being considered.
14+
* 5. If `nums[mid]` is 0, swap it with `nums[low]` and increment both `low` and `mid`.
15+
* 6. If `nums[mid]` is 1, it's in the correct place, so just increment `mid`.
16+
* 7. If `nums[mid]` is 2, swap it with `nums[high]` and decrement `high` (don't increment `mid` as the swapped element needs to be processed).
17+
*
18+
* ### Complexity
19+
* - **Time Complexity:** O(n), where 'n' is the number of elements, because we iterate through the array only once.
20+
* - **Space Complexity:** O(1), as the sorting is done in-place without using any extra data structures.
21+
*/
22+
public class DutchNationalFlagProblem {
23+
24+
public static void sortColors(int[] nums) {
25+
if (nums == null || nums.length == 0) {
26+
return;
27+
}
28+
29+
int low = 0;
30+
int mid = 0;
31+
int high = nums.length - 1;
32+
33+
while (mid <= high) {
34+
switch (nums[mid]) {
35+
case 0:
36+
// When the element is 0, swap it with the element at the low pointer
37+
swap(nums, low, mid);
38+
low++;
39+
mid++;
40+
break;
41+
case 1:
42+
// When the element is 1, it's in its correct place
43+
mid++;
44+
break;
45+
case 2:
46+
// When the element is 2, swap it with the element at the high pointer
47+
swap(nums, mid, high);
48+
high--;
49+
// Do not increment mid, as the swapped element from high needs to be checked
50+
break;
51+
}
52+
}
53+
}
54+
55+
private static void swap(int[] nums, int i, int j) {
56+
int temp = nums[i];
57+
nums[i] = nums[j];
58+
nums[j] = temp;
59+
}
60+
61+
/**
62+
* Main method for testing the Dutch National Flag Problem implementation.
63+
*/
64+
public static void main(String[] args) {
65+
// Test Case 1: Mixed array
66+
int[] colors1 = {2, 0, 2, 1, 1, 0};
67+
System.out.println("Test Case 1:");
68+
System.out.println("Original: " + Arrays.toString(colors1));
69+
sortColors(colors1);
70+
System.out.println("Expected: [0, 0, 1, 1, 2, 2]");
71+
System.out.println("Actual: " + Arrays.toString(colors1));
72+
System.out.println();
73+
74+
// Test Case 2: Array is already sorted
75+
int[] colors2 = {0, 0, 1, 2, 2};
76+
System.out.println("Test Case 2:");
77+
System.out.println("Original: " + Arrays.toString(colors2));
78+
sortColors(colors2);
79+
System.out.println("Expected: [0, 0, 1, 2, 2]");
80+
System.out.println("Actual: " + Arrays.toString(colors2));
81+
System.out.println();
82+
83+
// Test Case 3: Array with only two kinds of elements
84+
int[] colors3 = {2, 1, 1, 0, 0};
85+
System.out.println("Test Case 3:");
86+
System.out.println("Original: " + Arrays.toString(colors3));
87+
sortColors(colors3);
88+
System.out.println("Expected: [0, 0, 1, 1, 2]");
89+
System.out.println("Actual: " + Arrays.toString(colors3));
90+
System.out.println();
91+
}
92+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
/**
6+
* ## 3 Sum Problem
7+
*
8+
* This algorithm finds all unique triplets in an array of integers that sum up to zero.
9+
* It uses a two-pointer approach on a sorted version of the array to efficiently find the triplets.
10+
*
11+
* ### How it works:
12+
* 1. The input array is sorted to enable the two-pointer approach and to handle duplicates easily.
13+
* 2. We iterate through the array with a single pointer `i`.
14+
* 3. For each element `nums[i]`, we use two more pointers, `left` (starting at `i+1`) and `right` (starting at the end of the array).
15+
* 4. We calculate the sum of the three elements. If the sum is zero, we've found a triplet. If it's less than zero, we move `left` forward. If it's greater, we move `right` backward.
16+
* 5. Duplicates are skipped to ensure that each unique triplet is only added once.
17+
*
18+
* ### Complexity
19+
* - **Time Complexity:** O(n^2), where 'n' is the number of elements. The array sort is O(n log n), but the nested loop structure (a `for` loop and a `while` loop) dominates.
20+
* - **Space Complexity:** O(1) for the algorithm itself (if we don't count the space for the output list). Sorting is done in-place.
21+
*/
22+
public class ThreeSum {
23+
24+
public static List<List<Integer>> findTriplets(int[] nums) {
25+
// Sort the array to enable the two-pointer approach
26+
Arrays.sort(nums);
27+
List<List<Integer>> result = new ArrayList<>();
28+
29+
// Iterate through the array. We only need to go up to the third-to-last element.
30+
for (int i = 0; i < nums.length - 2; i++) {
31+
// Skip duplicate elements for the first element of the triplet to avoid duplicate results.
32+
if (i > 0 && nums[i] == nums[i - 1]) {
33+
continue;
34+
}
35+
36+
int left = i + 1;
37+
int right = nums.length - 1;
38+
while (left < right) {
39+
int currentSum = nums[i] + nums[left] + nums[right];
40+
if (currentSum == 0) {
41+
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
42+
// Skip duplicates for the second and third elements.
43+
while (left < right && nums[left] == nums[left + 1]) left++;
44+
while (left < right && nums[right] == nums[right - 1]) right--;
45+
left++;
46+
right--;
47+
} else if (currentSum < 0) {
48+
left++; // Sum is too small, need a larger number.
49+
} else {
50+
right--; // Sum is too large, need a smaller number.
51+
}
52+
}
53+
}
54+
return result;
55+
}
56+
57+
/**
58+
* Main method for testing the ThreeSum implementation.
59+
*/
60+
public static void main(String[] args) {
61+
// Test Case 1: Standard case with multiple solutions
62+
int[] nums1 = {-1, 0, 1, 2, -1, -4};
63+
System.out.println("Test Case 1:");
64+
System.out.println("Input: " + Arrays.toString(nums1));
65+
System.out.println("Expected: [[-1, -1, 2], [-1, 0, 1]]");
66+
System.out.println("Actual: " + findTriplets(nums1));
67+
System.out.println();
68+
69+
// Test Case 2: Array with no solution
70+
int[] nums2 = {1, 2, 3};
71+
System.out.println("Test Case 2:");
72+
System.out.println("Input: " + Arrays.toString(nums2));
73+
System.out.println("Expected: []");
74+
System.out.println("Actual: " + findTriplets(nums2));
75+
System.out.println();
76+
77+
// Test Case 3: Array with all zeros
78+
int[] nums3 = {0, 0, 0, 0};
79+
System.out.println("Test Case 3:");
80+
System.out.println("Input: " + Arrays.toString(nums3));
81+
System.out.println("Expected: [[0, 0, 0]]");
82+
System.out.println("Actual: " + findTriplets(nums3));
83+
System.out.println();
84+
}
85+
}

0 commit comments

Comments
 (0)