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)
|
* [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)
|
* [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)
|
* [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)
|
* [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)
|
* [MinPriorityQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
|
||||||
* lists
|
* lists
|
||||||
@ -860,6 +861,7 @@
|
|||||||
* [KthElementFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java)
|
* [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)
|
* [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)
|
* [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)
|
* [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
|
||||||
* lists
|
* lists
|
||||||
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
|
* [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