Skip to content

Commit 63b98ec

Browse files
author
sailok.chinta
committed
feat: Merge branch 'dnf-clean-up' of https://github.com/sailok/Java into dnf-clean-up
2 parents 5ced7e7 + 8e7b81e commit 63b98ec

File tree

4 files changed

+210
-28
lines changed

4 files changed

+210
-28
lines changed

DIRECTORY.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
* [SearchSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java)
157157
* [SinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java)
158158
* [SkipList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java)
159+
* [SortedLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java)
159160
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/Node.java)
160161
* queues
161162
* [CircularQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java)
@@ -268,6 +269,7 @@
268269
* [FractionalKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java)
269270
* [GaleShapley](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java)
270271
* [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java)
272+
* [MergeIntervals](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java)
271273
* [MinimizingLateness](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java)
272274
* io
273275
* [BufferedReader](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/io/BufferedReader.java)
@@ -450,6 +452,8 @@
450452
* [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TowerOfHanoi.java)
451453
* [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java)
452454
* [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java)
455+
* Recursion
456+
* [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java)
453457
* scheduling
454458
* [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
455459
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
@@ -499,7 +503,6 @@
499503
* [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java)
500504
* [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java)
501505
* [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java)
502-
* [DNFSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DNFSort.java)
503506
* [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java)
504507
* [DutchNationalFlagSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java)
505508
* [ExchangeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ExchangeSort.java)
@@ -684,6 +687,7 @@
684687
* [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)
685688
* [SinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java)
686689
* [SkipListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java)
690+
* [SortedLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SortedLinkedListTest.java)
687691
* queues
688692
* [CircularQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java)
689693
* [DequeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java)
@@ -753,6 +757,7 @@
753757
* [FractionalKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java)
754758
* [GaleShapleyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java)
755759
* [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java)
760+
* [MergeIntervalsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java)
756761
* [MinimizingLatenessTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java)
757762
* io
758763
* [BufferedReaderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/io/BufferedReaderTest.java)
@@ -892,6 +897,8 @@
892897
* [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java)
893898
* [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java)
894899
* [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java)
900+
* Recursion
901+
* [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/Recursion/GenerateSubsetsTest.java)
895902
* scheduling
896903
* [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
897904
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.thealgorithms.greedyalgorithms;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
/**
8+
* Problem Statement:
9+
* Given an array of intervals where intervals[i] = [starti, endi].
10+
*
11+
* Merge all overlapping intervals and return an array of the non-overlapping
12+
* intervals
13+
* that cover all the intervals in the input.
14+
*/
15+
public final class MergeIntervals {
16+
17+
/**
18+
* Private constructor to prevent instantiation of this utility class.
19+
*/
20+
private MergeIntervals() {
21+
}
22+
23+
/**
24+
* Merges overlapping intervals from the given array of intervals.
25+
*
26+
* The method sorts the intervals by their start time, then iterates through the
27+
* sorted intervals
28+
* and merges overlapping intervals. If an interval overlaps with the last
29+
* merged interval,
30+
* it updates the end time of the last merged interval. Otherwise, it adds the
31+
* interval as a new entry.
32+
*
33+
* @param intervals A 2D array representing intervals where each element is an
34+
* interval [starti, endi].
35+
* @return A 2D array of merged intervals where no intervals overlap.
36+
*
37+
* Example:
38+
* Input: {{1, 3}, {2, 6}, {8, 10}, {15, 18}}
39+
* Output: {{1, 6}, {8, 10}, {15, 18}}
40+
*/
41+
public static int[][] merge(int[][] intervals) {
42+
// Sort the intervals by their start time (ascending order)
43+
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
44+
45+
// List to store merged intervals
46+
List<int[]> merged = new ArrayList<>();
47+
48+
for (int[] interval : intervals) { // Each interval
49+
// If the merged list is empty or the current interval does not overlap with
50+
// the last merged interval, add it to the merged list.
51+
if (merged.isEmpty() || interval[0] > merged.get(merged.size() - 1)[1]) {
52+
merged.add(interval);
53+
} else {
54+
// If there is an overlap, merge the intervals by updating the end time
55+
// of the last merged interval to the maximum end time between the two
56+
// intervals.
57+
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], interval[1]);
58+
}
59+
}
60+
61+
// Convert the list of merged intervals back to a 2D array and return it
62+
return merged.toArray(new int[merged.size()][]);
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,127 @@
11
package com.thealgorithms.searches;
22

3-
/*
4-
To apply this method, the provided array must be strictly sorted. In this method, two pointers, one
5-
at 0th row & the other at the last row are taken & the searching is done on the basis of the middle
6-
element of the middle column. If that element is equal to target, its coordinates are returned, else
7-
if it is smaller than the target, the rows above that element are ignored (because the elements
8-
above it will also be smaller than the target), else that element is greater than the target, then
9-
the rows below it are ignored.
3+
/**
4+
* This class provides a method to search for a target value in a 2D sorted
5+
* array.
6+
* The search is performed using a combination of binary search on rows and
7+
* columns.
8+
* The 2D array must be strictly sorted in both rows and columns.
9+
*
10+
* The algorithm works by:
11+
* 1. Performing a binary search on the middle column of the 2D array.
12+
* 2. Depending on the value found, it eliminates rows above or below the middle
13+
* element.
14+
* 3. After finding or eliminating rows, it further applies binary search in the
15+
* relevant columns.
1016
*/
1117
public final class BinarySearch2dArray {
18+
1219
private BinarySearch2dArray() {
1320
}
1421

22+
/**
23+
* Performs a binary search on a 2D sorted array to find the target value.
24+
* The array must be sorted in ascending order in both rows and columns.
25+
*
26+
* @param arr The 2D array to search in.
27+
* @param target The value to search for.
28+
* @return An array containing the row and column indices of the target, or [-1,
29+
* -1] if the target is not found.
30+
*/
1531
static int[] binarySearch(int[][] arr, int target) {
1632
int rowCount = arr.length;
1733
int colCount = arr[0].length;
1834

35+
// Edge case: If there's only one row, search that row directly.
1936
if (rowCount == 1) {
2037
return binarySearch(arr, target, 0, 0, colCount);
2138
}
2239

40+
// Set initial boundaries for binary search on rows.
2341
int startRow = 0;
2442
int endRow = rowCount - 1;
25-
int midCol = colCount / 2;
43+
int midCol = colCount / 2; // Middle column index for comparison.
2644

45+
// Perform binary search on rows based on the middle column.
2746
while (startRow < endRow - 1) {
28-
int midRow = startRow + (endRow - startRow) / 2; // getting the index of middle row
47+
int midRow = startRow + (endRow - startRow) / 2;
2948

49+
// If the middle element matches the target, return its position.
3050
if (arr[midRow][midCol] == target) {
3151
return new int[] {midRow, midCol};
32-
} else if (arr[midRow][midCol] < target) {
52+
}
53+
// If the middle element is smaller than the target, discard the upper half.
54+
else if (arr[midRow][midCol] < target) {
3355
startRow = midRow;
34-
} else {
56+
}
57+
// If the middle element is larger than the target, discard the lower half.
58+
else {
3559
endRow = midRow;
3660
}
3761
}
38-
/*
39-
if the above search fails to find the target element, these conditions will be used to
40-
find the target element, which further uses the binary search algorithm in the places
41-
which were left unexplored.
42-
*/
62+
63+
// If the target wasn't found during the row search, check the middle column of
64+
// startRow and endRow.
4365
if (arr[startRow][midCol] == target) {
44-
return new int[] {
45-
startRow,
46-
midCol,
47-
};
66+
return new int[] {startRow, midCol};
4867
}
4968

5069
if (arr[endRow][midCol] == target) {
5170
return new int[] {endRow, midCol};
5271
}
5372

73+
// If target is smaller than the element in the left of startRow, perform a
74+
// binary search on the left of startRow.
5475
if (target <= arr[startRow][midCol - 1]) {
5576
return binarySearch(arr, target, startRow, 0, midCol - 1);
5677
}
5778

79+
// If target is between midCol and the last column of startRow, perform a binary
80+
// search on that part of the row.
5881
if (target >= arr[startRow][midCol + 1] && target <= arr[startRow][colCount - 1]) {
5982
return binarySearch(arr, target, startRow, midCol + 1, colCount - 1);
6083
}
6184

85+
// If target is smaller than the element in the left of endRow, perform a binary
86+
// search on the left of endRow.
6287
if (target <= arr[endRow][midCol - 1]) {
6388
return binarySearch(arr, target, endRow, 0, midCol - 1);
6489
} else {
90+
// Otherwise, search on the right of endRow.
6591
return binarySearch(arr, target, endRow, midCol + 1, colCount - 1);
6692
}
6793
}
6894

95+
/**
96+
* Performs a binary search on a specific row of the 2D array.
97+
*
98+
* @param arr The 2D array to search in.
99+
* @param target The value to search for.
100+
* @param row The row index where the target will be searched.
101+
* @param colStart The starting column index for the search.
102+
* @param colEnd The ending column index for the search.
103+
* @return An array containing the row and column indices of the target, or [-1,
104+
* -1] if the target is not found.
105+
*/
69106
static int[] binarySearch(int[][] arr, int target, int row, int colStart, int colEnd) {
107+
// Perform binary search within the specified column range.
70108
while (colStart <= colEnd) {
71109
int midIndex = colStart + (colEnd - colStart) / 2;
72110

111+
// If the middle element matches the target, return its position.
73112
if (arr[row][midIndex] == target) {
74-
return new int[] {
75-
row,
76-
midIndex,
77-
};
78-
} else if (arr[row][midIndex] < target) {
113+
return new int[] {row, midIndex};
114+
}
115+
// If the middle element is smaller than the target, move to the right half.
116+
else if (arr[row][midIndex] < target) {
79117
colStart = midIndex + 1;
80-
} else {
118+
}
119+
// If the middle element is larger than the target, move to the left half.
120+
else {
81121
colEnd = midIndex - 1;
82122
}
83123
}
84124

85-
return new int[] {-1, -1};
125+
return new int[] {-1, -1}; // Target not found
86126
}
87127
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.thealgorithms.greedyalgorithms;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class MergeIntervalsTest {
8+
9+
@Test
10+
public void testMergeIntervalsWithOverlappingIntervals() {
11+
// Test case where some intervals overlap and should be merged
12+
int[][] intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
13+
int[][] expected = {{1, 6}, {8, 10}, {15, 18}};
14+
int[][] result = MergeIntervals.merge(intervals);
15+
assertArrayEquals(expected, result);
16+
}
17+
18+
@Test
19+
public void testMergeIntervalsWithNoOverlap() {
20+
// Test case where intervals do not overlap
21+
int[][] intervals = {{1, 2}, {3, 4}, {5, 6}};
22+
int[][] expected = {{1, 2}, {3, 4}, {5, 6}};
23+
int[][] result = MergeIntervals.merge(intervals);
24+
assertArrayEquals(expected, result);
25+
}
26+
27+
@Test
28+
public void testMergeIntervalsWithCompleteOverlap() {
29+
// Test case where intervals completely overlap
30+
int[][] intervals = {{1, 5}, {2, 4}, {3, 6}};
31+
int[][] expected = {{1, 6}};
32+
int[][] result = MergeIntervals.merge(intervals);
33+
assertArrayEquals(expected, result);
34+
}
35+
36+
@Test
37+
public void testMergeIntervalsWithSingleInterval() {
38+
// Test case where only one interval is given
39+
int[][] intervals = {{1, 2}};
40+
int[][] expected = {{1, 2}};
41+
int[][] result = MergeIntervals.merge(intervals);
42+
assertArrayEquals(expected, result);
43+
}
44+
45+
@Test
46+
public void testMergeIntervalsWithEmptyArray() {
47+
// Test case where the input array is empty
48+
int[][] intervals = {};
49+
int[][] expected = {};
50+
int[][] result = MergeIntervals.merge(intervals);
51+
assertArrayEquals(expected, result);
52+
}
53+
54+
@Test
55+
public void testMergeIntervalsWithIdenticalIntervals() {
56+
// Test case where multiple identical intervals are given
57+
int[][] intervals = {{1, 3}, {1, 3}, {1, 3}};
58+
int[][] expected = {{1, 3}};
59+
int[][] result = MergeIntervals.merge(intervals);
60+
assertArrayEquals(expected, result);
61+
}
62+
63+
@Test
64+
public void testMergeIntervalsWithRandomIntervals() {
65+
// Test case with a mix of overlapping and non-overlapping intervals
66+
int[][] intervals = {{1, 4}, {5, 7}, {2, 6}, {8, 10}};
67+
int[][] expected = {{1, 7}, {8, 10}};
68+
int[][] result = MergeIntervals.merge(intervals);
69+
assertArrayEquals(expected, result);
70+
}
71+
}

0 commit comments

Comments
 (0)