public ListNode heapSolution(List<ListNode> lists) {
    if (lists == null || lists.size() == 0)
      return null;
    int k = lists.size();
    // use a queue to represent the heap and define its own comparator
    Queue<ListNode> minHeap = new PriorityQueue<ListNode>(k,
        new Comparator<ListNode>() {
          @Override
          public int compare(ListNode o1, ListNode o2) {
            if (o1 == null)
              return 1;
            else if (o2 == null)
              return -1;
            else
              return o1.val - o2.val;
          }
        });
    for (ListNode root : lists) {
      if (root != null) {
        minHeap.add(root);
      }
    }
    ListNode dummy = new ListNode(0);
    ListNode cur = dummy;
    while (minHeap.size() != 0) {
      ListNode root = minHeap.poll();
      cur.next = root;
      cur = root;
      if (root.next != null) {
        minHeap.add(root.next);
      }
    }
    return dummy.next;
  }