前言:由于平时荒废了学习工作,等到想要找工作才发现已经遗忘忘了,开始重新刷算法题。
合并两个有序链表已经知道怎么做了,那么如果合并多个有序链表呢?
我想到的几种方法
1.使用优先级队列来解决问题,将链表的头节点放入优先级队列中,每次从队列中取出链表的节点,然后将链表的下个节点放入优先级队列中,重复以上操作,直至队列中没有链表为止。
public class MergeKSortedLists {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
//此处用lamda表达式写的 为了简约
PriorityQueue<ListNode> minHeap = new PriorityQueue<>((a, b) -> a.val - b.val);
for (ListNode list : lists) {
if (list != null) {
minHeap.offer(list);
}
}
//定义虚拟头节点 避免出现空指针问题
ListNode dummy = new ListNode(0);
ListNode current = dummy;
//直至队列中元素取完
while (!minHeap.isEmpty()) {
ListNode node = minHeap.poll();
current.next = node;
current = current.next;
if (node.next != null) {
minHeap.offer(node.next);
}
}
//返回虚拟节点的下个节点
return dummy.next;
}
}
2.由于上次用了拉链法来解决这个问题,同样的此次这个问题也可以递归使用拉链法继续解决
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
public class MergeKSortedLists {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
return mergeLists(lists, 0, lists.length - 1);
}
private ListNode mergeLists(ListNode[] lists, int start, int end) {
if (start == end) {
return lists[start];
}
int mid = start + (end - start) / 2;
ListNode left = mergeLists(lists, start, mid);
ListNode right = mergeLists(lists, mid + 1, end);
return mergeTwoLists(left, right);
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode current = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
if (l1 != null) {
current.next = l1;
} else {
current.next = l2;
}
return dummy.next;
}
}
这段代码中,我们定义了一个ListNode
类来表示链表节点,并创建了一个MergeKSortedLists
类,其中包含了合并k个有序链表的方法mergeKLists
。主要的合并逻辑在mergeLists
和mergeTwoLists
方法中实现。
mergeKLists
方法首先检查传入的链表数组是否为空,然后调用mergeLists
方法来递归地合并所有的链表。
mergeLists
方法使用分治法将链表数组划分为两部分,然后递归地合并左半部分和右半部分。最后,合并两个有序链表的逻辑在mergeTwoLists
方法中完成,将两个链表按升序合并成一个。
你可以使用这个类来合并k个有序链表,只需创建ListNode
对象表示链表,然后调用mergeKLists
方法即可。