mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-07 01:35:16 +08:00
Add MergeKSortedArrays
algorithm (#5838)
This commit is contained in:
@ -179,6 +179,7 @@
|
||||
* [LeftistHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java)
|
||||
* [MaxHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java)
|
||||
* [MedianFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java)
|
||||
* [MergeKSortedArrays](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java)
|
||||
* [MinHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java)
|
||||
* [MinPriorityQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
|
||||
* lists
|
||||
@ -860,6 +861,7 @@
|
||||
* [KthElementFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java)
|
||||
* [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
|
||||
* [MedianFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java)
|
||||
* [MergeKSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java)
|
||||
* [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
|
||||
* lists
|
||||
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.thealgorithms.datastructures.heaps;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* This class provides a method to merge multiple sorted arrays into a single sorted array.
|
||||
* It utilizes a min-heap to efficiently retrieve the smallest elements from each array.
|
||||
*
|
||||
* Time Complexity: O(n * log k), where n is the total number of elements across all arrays
|
||||
* and k is the number of arrays.
|
||||
*
|
||||
* Space Complexity: O(k) for the heap, where k is the number of arrays.
|
||||
*
|
||||
* @author Hardvan
|
||||
*/
|
||||
public final class MergeKSortedArrays {
|
||||
private MergeKSortedArrays() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges k sorted arrays into one sorted array using a min-heap.
|
||||
* Steps:
|
||||
* 1. Create a min-heap to store elements in the format: {value, array index, element index}
|
||||
* 2. Add the first element from each array to the heap
|
||||
* 3. While the heap is not empty, remove the smallest element from the heap
|
||||
* and add it to the result array. If there are more elements in the same array,
|
||||
* add the next element to the heap.
|
||||
* Continue until all elements have been processed.
|
||||
* The result array will contain all elements in sorted order.
|
||||
* 4. Return the result array.
|
||||
*
|
||||
* @param arrays a 2D array, where each subarray is sorted in non-decreasing order
|
||||
* @return a single sorted array containing all elements from the input arrays
|
||||
*/
|
||||
public static int[] mergeKArrays(int[][] arrays) {
|
||||
PriorityQueue<int[]> minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
|
||||
|
||||
int totalLength = 0;
|
||||
for (int i = 0; i < arrays.length; i++) {
|
||||
if (arrays[i].length > 0) {
|
||||
minHeap.offer(new int[] {arrays[i][0], i, 0});
|
||||
totalLength += arrays[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
int[] result = new int[totalLength];
|
||||
int index = 0;
|
||||
while (!minHeap.isEmpty()) {
|
||||
int[] top = minHeap.poll();
|
||||
result[index++] = top[0];
|
||||
|
||||
if (top[2] + 1 < arrays[top[1]].length) {
|
||||
minHeap.offer(new int[] {arrays[top[1]][top[2] + 1], top[1], top[2] + 1});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.thealgorithms.datastructures.heaps;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class MergeKSortedArraysTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideTestCases")
|
||||
public void testMergeKArrays(int[][] arrays, int[] expected) {
|
||||
assertArrayEquals(expected, MergeKSortedArrays.mergeKArrays(arrays));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> provideTestCases() {
|
||||
return Stream.of(
|
||||
// Basic test case with multiple arrays
|
||||
Arguments.of(new int[][] {{1, 4, 5}, {1, 3, 4}, {2, 6}}, new int[] {1, 1, 2, 3, 4, 4, 5, 6}),
|
||||
|
||||
// Edge case: All arrays are empty
|
||||
Arguments.of(new int[][] {{}, {}, {}}, new int[] {}),
|
||||
|
||||
// Edge case: One array is empty
|
||||
Arguments.of(new int[][] {{1, 3, 5}, {}, {2, 4, 6}}, new int[] {1, 2, 3, 4, 5, 6}),
|
||||
|
||||
// Single array
|
||||
Arguments.of(new int[][] {{1, 2, 3}}, new int[] {1, 2, 3}),
|
||||
|
||||
// Arrays with negative numbers
|
||||
Arguments.of(new int[][] {{-5, 1, 3}, {-10, 0, 2}}, new int[] {-10, -5, 0, 1, 2, 3}),
|
||||
|
||||
// Arrays with duplicate elements
|
||||
Arguments.of(new int[][] {{1, 1, 2}, {1, 3, 3}, {2, 2, 4}}, new int[] {1, 1, 1, 2, 2, 2, 3, 3, 4}),
|
||||
|
||||
// Edge case: Arrays of varying lengths
|
||||
Arguments.of(new int[][] {{1, 2}, {3}, {4, 5, 6, 7}}, new int[] {1, 2, 3, 4, 5, 6, 7}));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user