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個。