Merge k Sorted Lists
Problem
Every input line is one list of integers, already sorted from small to big. Merge all lines into one sorted list and print it, numbers separated by spaces.
Constraints
- 1 <= k <= 100
- |value| <= 10^9
- each line is sorted and not empty
Examples
Input
1 4 5 1 3 4 2 6
Output
1 1 2 3 4 4 5 6
Solutions
The heap always holds the front number of every list. The smallest one is the next answer, and its list supplies the next candidate. For N numbers in total the cost is O(N log k).
/*
* Problem : Process lines.
* Input : Several lines.
* Output : The merged list.
* Approach: Heap.
* Time : O(N log k)
* Space : O(k)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String solve(String[] lines) {
// Step 1: Read the lists. The heap holds {value, list number, position}. It always gives the smallest value of the front numbers.
int k = lines.length;
long[][] lists = new long[k][];
java.util.PriorityQueue<long[]> heap = new java.util.PriorityQueue<long[]>((x, y) -> Long.compare(x[0], y[0]));
for (int i = 0; i < k; i++) {
String[] part = lines[i].split(" ");
lists[i] = new long[part.length];
for (int j = 0; j < part.length; j++) {
lists[i][j] = Long.parseLong(part[j]);
}
heap.add(new long[] {lists[i][0], i, 0});
}
// Step 2: Take the smallest, write it, and push the next number of the same list.
StringBuilder result = new StringBuilder();
while (!heap.isEmpty()) {
long[] top = heap.poll();
result.append(result.length() == 0 ? "" : " ").append(top[0]);
int list = (int) top[1];
int next = (int) top[2] + 1;
if (next < lists[list].length) {
heap.add(new long[] {lists[list][next], list, next});
}
}
return result.toString();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(solve(lines));
}
}
Hints (2)
- How many items does the heap hold at most?
- What do we push after a pop?