package leetcode;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import leetcode.api.ListNode;

/**
 * https://leetcode.com/problems/merge-k-sorted-lists
 */
@SuppressWarnings("ClassCanBeStatic") // TODO move to api package
public final class Problem23MergeKLists {
    // Time - O(N*LOG(K))
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) {
            return null;
        }

        Queue<ListNode> queue =
            new PriorityQueue<>(Comparator.comparingInt(left -> left.val));

        for (ListNode listNode : lists) {
            if (listNode != null) {
                queue.add(listNode);
            }
        }

        ListNode head = new ListNode(0);
        ListNode tail = head;

        while (!queue.isEmpty()) {
            tail.next = queue.poll();
            tail = tail.next;

            if (tail.next != null) {
                queue.add(tail.next);
            }
        }

        return head.next;
    }

    // Time - O(N*LOG(K))
    public List<Integer> mergeKLists(int[][] arrays) {
        List<Integer> toReturn = new ArrayList<>();
        if (arrays == null || arrays.length == 0 || arrays[0].length == 0) {
            return toReturn;
        }

        Queue<Node> queue = new PriorityQueue<>((left, right) -> {
            if (left.hasData() && right.hasData()) {
                return Integer.compare(left.array[left.pos], right.array[right.pos]);
            }

            return left.hasData() ? left.array[left.pos] : right.array[right.pos];
        });

        for (int[] array : arrays) {
            Node node = new Node(array);
            queue.add(node);
        }

        while (!queue.isEmpty()) {
            Node node = queue.poll();
            if (node.hasData()) {
                toReturn.add(node.array[node.pos]);
                node.pos++;
                queue.add(node);
            }
        }

        return toReturn;
    }

    private class Node {
        final int[] array;
        int pos;

        public Node(int[] array) {
            this.array = array;
        }

        public boolean hasData() {
            return pos < array.length;
        }
    }
}

@@ -33,69 +33,18 @@
 til.
-ArrayList;%0Aimport java.util.Comparator;%0Aimport java.util.List
+Comparator
 ;%0Aim
@@ -979,32 +979,32 @@
    %7D%0A        %7D%0A%0A
+
         return h
@@ -1022,1208 +1022,7 @@
    %7D
-%0A%0A    // Time - O(N*LOG(K))%0A    public List%3CInteger%3E mergeKLists(int%5B%5D%5B%5D arrays) %7B%0A        List%3CInteger%3E toReturn = new ArrayList%3C%3E();%0A        if (arrays == null %7C%7C arrays.length == 0 %7C%7C arrays%5B0%5D.length == 0) %7B%0A            return toReturn;%0A        %7D%0A%0A        Queue%3CNode%3E queue = new PriorityQueue%3C%3E((left, right) -%3E %7B%0A            if (left.hasData() && right.hasData()) %7B%0A                return Integer.compare(left.array%5Bleft.pos%5D, right.array%5Bright.pos%5D);%0A            %7D%0A%0A            return left.hasData() ? left.array%5Bleft.pos%5D : right.array%5Bright.pos%5D;%0A        %7D);%0A%0A        for (int%5B%5D array : arrays) %7B%0A            Node node = new Node(array);%0A            queue.add(node);%0A        %7D%0A%0A        while (!queue.isEmpty()) %7B%0A            Node node = queue.poll();%0A            if (node.hasData()) %7B%0A                toReturn.add(node.array%5Bnode.pos%5D);%0A                node.pos++;%0A                queue.add(node);%0A            %7D%0A        %7D%0A%0A        return toReturn;%0A    %7D%0A%0A    private class Node %7B%0A        final int%5B%5D array;%0A        int pos;%0A%0A        public Node(int%5B%5D array) %7B%0A            this.array = array;%0A        %7D%0A%0A        public boolean hasData() %7B%0A            return pos %3C array.length;%0A        %7D%0A    %7D
 %0A%7D%0A

remove extra answer