23 合并k个升序链表
顺序合并01
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if(lists.length==0){
return null;
}
if(lists.length==1){
return lists[0];
}
ListNode res = new ListNode();
res = lists[0];
for(int i=1;i<len;i++){
res = merge(res,lists[i]);
}
return res;
}
public ListNode merge(ListNode list1,ListNode list2){
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
ListNode pre = new ListNode();
ListNode cur = list1;
ListNode p2 = list2;
while(cur!=null && p2!=null){
if(cur.val<p2.val){
pre = cur;
cur = cur.next;
}else{
pre.next = p2;
p2 = p2.next;
pre.next.next=cur;
pre = pre.next;
}
}
if (p2!=null){
pre.next=p2;
}
if (list1.val<list2.val){
return list1;
}
return list2;
}
}
时间复杂度
O
(
k
2
n
)
O(k^2n)
O(k2n)。假设每个链表的最长长度是
n
n
n。第一次合并后
r
e
s
res
res的长度为
2
n
2n
2n,第
i
i
i次合并后,
r
e
s
res
res的长度为
(
i
−
1
)
×
n
(i-1)\times n
(i−1)×n。第
i
i
i次合并的代价是
O
(
(
i
−
2
)
n
+
n
)
O((i-2)n+n)
O((i−2)n+n)。总的时间代价是
O
(
k
2
n
)
O(k^2n)
O(k2n)。
空间复杂度
O
(
1
)
O(1)
O(1)。
顺序合并02
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if(lists.length==0){
return null;
}
if(lists.length==1){
return lists[0];
}
ListNode res = new ListNode();
res = lists[0];
for(int i=1;i<len;i++){
res = merge(res,lists[i]);
}
return res;
}
public ListNode merge(ListNode list1,ListNode list2){
ListNode head = new ListNode();
ListNode p = head;
ListNode p1 = list1;
ListNode p2 = list2;
while(p1!=null && p2!=null){
if(p1.val<p2.val){
p.next = p1;
p=p.next;
p1 = p1.next;
}else{
p.next=p2;
p=p.next;
p2=p2.next;
}
}
if (p1!=null){
p.next=p1;
}
if(p2!=null){
p.next=p2;
}
return head.next;
}
}
同上。
分治合并
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return mergeList(lists,0,lists.length-1);
}
public ListNode mergeList(ListNode[] lists,int l,int r){
if(l==r){
return lists[l];
}
if (l>r){
return null;
}
int mid = (l+r)/2;
return merge(mergeList(lists,l,mid),mergeList(lists,mid+1,r));
}
public ListNode merge(ListNode list1,ListNode list2){
ListNode head = new ListNode();
ListNode p = head;
ListNode p1 = list1;
ListNode p2 = list2;
while(p1!=null && p2!=null){
if(p1.val<p2.val){
p.next = p1;
p=p.next;
p1 = p1.next;
}else{
p.next=p2;
p=p.next;
p2=p2.next;
}
}
if (p1!=null){
p.next=p1;
}
if(p2!=null){
p.next=p2;
}
return head.next;
}
}
时间复杂度
O
(
k
log
k
∗
n
)
O(k\log k *n)
O(klogk∗n)。
空间复杂度
O
(
log
k
)
O(\log k)
O(logk)。
优先队列
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length==0){
return null;
}
if(lists.length==1){
return lists[0];
}
PriorityQueue<ListNode> que = new PriorityQueue<>(new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val-o2.val;
}
});
ListNode head = new ListNode(0);
ListNode p = head;
for(int i=0;i<lists.length;i++){
if(lists[i]==null){
continue;
}
que.add(lists[i]);
}
while (!que.isEmpty()){
ListNode tmp = que.poll();
if (tmp==null){
continue;
}
p.next = tmp;
p=p.next;
tmp=tmp.next;
if (tmp!=null){
que.add(tmp);
}
}
return head.next;
}
}
时间复杂度
O
(
k
n
×
log
k
)
O(kn \times \log k)
O(kn×logk)。优先队列中的元素不超过
k
k
k个,那么插入和删除的时间代价为
O
(
log
k
)
O(\log k)
O(logk),这里最多有
k
n
kn
kn个点,对于每个点都被插入和删除一次,故总的时间代价即为
O
(
k
n
×
log
k
)
O(kn \times \log k)
O(kn×logk)。
空间复杂度
O
(
k
)
O(k)
O(k),优先队列中的元素不超过
k
k
k个。