题目:
给定K个升序链表,将链表合并,并返回合并后链表的head节点(主要用到了上期博客中提到的PriorityQueue和比较器,不了解的可以去看下)。
分析:
可将K个节点的head都放入PriorityQueue中并指定排序方法,小的弹出,并将下一节点压入 关于PriorityQueue
- 遍历Node数组,将每一个链表的head放入PriorityQueue中。
- PriorityQueue.poll()方法,弹出PriorityQueue中最小的Node节点作为新链表的head。
- 将最小head节点的next节点压入PriorityQueue中,并声明变量pre = head,用来链接head的下一个节点。
- 循环,如果PriorityQueue不为空。
- 再次弹出PriorityQueue中最小节点cur,获取,并将pre的next指针指向cur,pre = cur(获取到当前新链表的节点,目的下次找到最小节点的指向)。
- 如果当前弹出Node的next不为null,则将下一节点压入PriorityQueue
完整代码
public static class Node {
public int val;
public Node next;
public Node(int value) {
this.val = value;
}
}
//根据Node的val属性进行排序
public static class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
return o1.val - o2.val;
}
}
public static Node mergeNode(Node[] nodes) {
if (nodes == null) {
return null;
}
//创建优先级队列,并指定排序规则
PriorityQueue<Node> priorityQueue = new PriorityQueue<>(new NodeComparator());
//将每个链表的head节点加入到队列中
for (int i = 0; i < nodes.length; i++) {
if (nodes[i] != null) {
priorityQueue.add(nodes[i]);
}
}
if (priorityQueue.isEmpty()) {
return null;
}
//弹出当前队列中最小节点,作为新链表的head节点
Node head = priorityQueue.poll();
//声明pre变量指向head,目的是找到新的最小节点后,head的next能够指向
Node pre = head;
//如果当前head的next不为null,则压入队列
if (pre.next != null) {
priorityQueue.add(pre.next);
}
//优先级队列不为空则一直遍历
while (!priorityQueue.isEmpty()) {
//弹出当前优先级队列中最小节点
Node cur = priorityQueue.poll();
//新head的next指针指向当前节点
pre.next = cur;
//记住当前节点,也是便于接下来的next指向
pre = cur;
//如果节点不为null,则继续压入priorityQueue
if (cur.next != null) {
priorityQueue.add(cur.next);
}
}
return head;
}
//测试
public static void main(String[] args) {
Node node1 = new Node(1);
node1.next = new Node(5);
node1.next.next = new Node(7);
Node node2 = new Node(1);
node2.next = new Node(4);
node2.next.next = new Node(8);
Node node3 = new Node(5);
node3.next = new Node(9);
node3.next.next = new Node(9);
Node[] nodes = {node1,node2,node3};
Node node = mergeNode(nodes);
while (node != null){
System.out.print(node.val + " ");
node = node.next;
}
}