题目
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/73d7ba323db8cdebb1b482aa4193f22f.png)
思路
- 想法肯定是K指针,但是这样做感觉复杂度太高了,再阴间一点就是遍历链表数组,全部加入一个vector或者arrrylist里,然后一个sort然后再建链表,但肯定不是考察这方面。直接润去题解。
- 首先了解一下如果是两个升序链表,规定需要O(1)的空间复杂度,那么不能使用双指针了(顺带一提,原来看起来最简洁的方法是递归,我为一直只知道双指针羞愧…)
- 于是重新回去写一遍链表合并,使用O(1)空间复杂度的方式,链接:https://blog.csdn.net/z754916067/article/details/123386965
- 第一种方法:在采用合并双链表的基础上,建立一个空指针ans,然后每一步把它和K个之一进行双合并。
- 第二种方法:分治法,建立在递归和两个链表合并的基础上,每次合并两个链表,再将合并好后的链表合并成大一点的链表,再合并,后附代码。
- 第三种方法:优先队列法,其实想法大致和K指针差不多,只是把比较过程采用了优先队列进行容纳,以大小为优先级,每次优先队列出的是最小的一个node。
代码(分治法)
public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode head = new ListNode();
ListNode l1 = list1;
ListNode l2 = list2;
ListNode now = head;
while(l1!=null && l2!=null){
if(l1.val==l2.val){
now.next=l1;
now=l1;
l1=l1.next;
now.next=l2;
now=l2;
l2=l2.next;
}else if(l1.val< l2.val){
now.next=l1;
now=l1;
l1=l1.next;
}else{
now.next=l2;
now=l2;
l2=l2.next;
}
}
if(l1==null) now.next=l2;
else if(l2==null) now.next=l1;
return head.next;
}
public static ListNode mergeKLists(ListNode[] lists) {
int l=0;
int r = lists.length-1;
return merge(lists,l,r);
}
public static ListNode merge(ListNode[] list1,int l,int r){
if(l==r) return list1[l];
if(l>r) return null;
int mid = (l+r)>>1;
return mergeTwoLists(merge(list1,l,mid),merge(list1,mid+1,r));
}
代码(优先队列)
public ListNode mergeKLists(ListNode[] lists) {
Queue<ListNode> pq = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);
for (ListNode node: lists) {
if (node != null) {
pq.offer(node);
}
}
ListNode Head = new ListNode(0);
ListNode tail = Head;
while (!pq.isEmpty()) {
ListNode minNode = pq.poll();
tail.next = minNode;
tail = minNode;
if (minNode.next != null) {
pq.offer(minNode.next);
}
}
return Head.next;
}