详细见:leetcode.com/problems/merge-k-sorted-lists/
解析:两两合并(Java),堆排序(C和Python)
Java Solution: github
package leetcode;
public class P023_MergeKSortedLists {
/*
* 1 2方法太垃圾了,
* 改用两次合并法
* 7ms
* 62.23%
* 还可以做很多改进
*/
static class Solution3 {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
int i = 0, j = 0, len = lists.length, iend = (len + 1) >>> 1;
while (iend != len) {
for (i = 0; i != iend; i ++) {
j = len - 1 - i;
if (i == j || lists[j] == null)
continue;
if (lists[i] == null) {
lists[i] = lists[j];
continue;
}
if (lists[i].val > lists[j].val) {
ListNode temp = lists[i];
lists[i] = lists[j];
lists[j] = temp;
}
mergeTwoLists(lists[i], lists[j]);
}
len = iend; iend = (len + 1) >>> 1;
}
return lists[0];
}
private void mergeTwoLists(ListNode c1, ListNode c2) {
while (c1.next != null && c2.next != null) {
if (c1.val <= c2.val) {
if (c1.next.val >= c2.val) {
ListNode temp = c2.next;
c2.next = c1.next;
c1.next = c2;
c2 = temp;
} else {
c1 = c1.next;
}
} else {
if (c2.next.val >= c1.val) {
ListNode temp = c1.next;
c1.next = c2.next;
c2.next = c1;
c1 = temp;
} else {
c2 = c2.next;
}
}
}
if (c1.next == null) {
c1.next = c2;
} else {
while (c1.next != null) {
if (c1.next.val > c2.val)
break;
c1 = c1.next;
}
if (c2 != null) {
if (c1.next != null) {
c2.next = c1.next;
}
c1.next = c2;
}
}
}
}
/*
* 更换更加高效的两链表合并算法
* 5ms
* 65.95%
*/
static class Solution4 {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
int i = 0, j = 0, len = lists.length, iend = (len + 1) >>> 1;
while (iend != len) {
for (i = 0; i != iend; i ++) {
j = len - 1 - i;
if (i == j || lists[j] == null)
continue;
if (lists[i] == null) {
lists[i] = lists[j];
continue;
}
if (lists[i].val > lists[j].val) {
ListNode temp = lists[i];
lists[i] = lists[j];
lists[j] = temp;
}
mergeTwoLists(lists[i], lists[j]);
}
len = iend; iend = (len + 1) >>> 1;
}
return lists[0];
}
private void mergeTwoLists(ListNode c1, ListNode c2) {
ListNode pre = c1; c1 = c1.next;
while (true) {
while (c1 != null && c1.val <= c2.val) {
pre = c1;
c1 = c1.next;
}
pre.next = c2;
if (c1 == null)
break;
while (c2 != null && c2.val <= c1.val) {
pre = c2;
c2 = c2.next;
}
pre.next = c1;
if (c2 == null)
break;
}
}
}
static class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
}
/*
url: leetcode.com/problems/merge-k-sorted-lists/
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct ListNode {
int val;
struct ListNode *next;
};
void print_ListNode(struct ListNode * h) {
while (h != NULL) {
printf("%d ", h->val);
h = h->next;
}
printf("\r\n");
}
int cmp(struct ListNode * l1, struct ListNode * l2) {
if (NULL == l1 && NULL == l2) return 0;
if (l1 == NULL) return 1;
if (l2 == NULL) return -1;
if (l1->val < l2->val)
return -1;
if (l1->val > l2->val)
return 1;
return 0;
}
void swap(struct ListNode ** l1, struct ListNode ** l2) {
struct ListNode * t = *l1;
*l1 = *l2;
*l2 = t;
}
void swap_heap(struct ListNode * heap, int i, int j) {
struct ListNode t = heap[i];
heap[i] = heap[j];
heap[j] = t;
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
struct ListNode* head = (struct ListNode *) malloc(sizeof(struct ListNode));
struct ListNode* travel = head;
struct ListNode* temp = NULL;
struct ListNode* heap = (struct ListNode *) malloc(sizeof(struct ListNode) * listsSize);
int i = 0, p = 0, c = 0, hi = 0;
if (listsSize == 0) return NULL;
head->next = NULL;
for (i = 0; i < listsSize; i ++) {
if (*(lists+ i) != 0)
*(heap + (hi ++)) = *(*(lists + i));
}
if (hi == 0) return NULL;
//build heap
for (i = (listsSize - 1) / 2; i > -1; i --) {
//heap down
p = i;
c = 2 * p + 1;
while (c < hi) {
if (c + 1 < hi && cmp(heap + c + 1, heap + c) < 0) c ++;
if (cmp(heap + p, heap + c) > 0) {
swap_heap(heap, p, c);
} else break;
p = c;
c = 2 * p + 1;
}
}
while (heap != NULL) {
temp = (struct ListNode *) malloc(sizeof(struct ListNode));
temp->val = heap->val;
temp->next = NULL;
travel->next = temp;
travel = temp;
if (heap->next == NULL) {
heap[0] = heap[hi - 1];
hi --;
if (hi == 0) break;
} else {
heap->val = heap->next->val;
heap->next = heap->next->next;
}
//*heap = *(heap->next);
//heap down
p = 0;
c = 2 * p + 1;
while (c < hi) {
if (c + 1 < hi && cmp(heap + c + 1, heap + c) < 0) c ++;
if (cmp(heap + p, heap + c) > 0) {
swap_heap(heap, p, c);
} else break;
p = c;
c = 2 * p + 1;
}
}
return head->next;
}
struct ListNode * convert_int_to_ListNode(int * arr, int n) {
struct ListNode * head = NULL;
struct ListNode * travel = NULL;
struct ListNode * temp = NULL;
int i = 0;
if (n == 0 || n < 0) return NULL;
travel = (struct ListNode *) malloc(sizeof(struct ListNode));
travel->val = *(arr + 0);
travel->next = NULL;
head = travel;
for (i = 1; i < n; i ++) {
temp = (struct ListNode *) malloc(sizeof(struct ListNode));
temp->val = *(arr + i);
temp->next = NULL;
travel->next = temp;
travel = travel->next;
}
return head;
}
void free_ListNode(struct ListNode * l) {
struct ListNode * temp = NULL;
while (l != NULL) {
temp = l->next;
free(l);
l = temp;
}
}
int main() {
struct ListNode** lists = NULL;
struct ListNode * temp = NULL;
int listsSize = 2;
int i = 0;
int len = 2;
int a0[] = {1, 3};
int *a1 = NULL;
int **a;
int count[] = {0, 2};
struct ListNode * answer = NULL;
a = (int **) malloc(sizeof(int *) * len);
*(a + 0) = a1;
*(a + 1) = a0;
lists = (struct ListNode **) malloc(sizeof(struct ListNode *) * listsSize);
for (i = 0; i < listsSize; i ++) {
*(lists + i) = convert_int_to_ListNode(*(a + i), count[i]);
}
answer = mergeKLists(lists, listsSize);
print_ListNode(answer);
free_ListNode(answer);
free(a);
for (i = 0; i < listsSize; i ++) {
free(*(lists + i));
}
free(lists);
printf("end\r\n");
return 0;
}
#coding=utf-8
'''
url: leetcode.com/problems/merge-k-sorted-lists/
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年3月29日
@details: Solution: 302ms 11.23%
'''
from leetcode.Utils import *
class Solution(object):
def cmp(self, a, b):
if a == None:
return 1
elif b == None:
return -1
return a.val - b.val
def swap(self, a, i, j):
t = a[i]
a[i] = a[j]
a[j] = t
def mergeKLists(self, ls):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
lsn = 0 if ls == None else len(ls)
if (lsn == 0): return []
heap, a, hi = [None] * lsn, None, 0
for i in range(lsn):
if ls[i] != None:
heap[hi] = ls[i]
hi += 1
if hi == 0: return a
for i in range((lsn - 1) // 2, -1, -1):
p = i
c = 2 * p + 1
while c < hi:
if c + 1 < hi and self.cmp(heap[c + 1], heap[c]) < 0:
c += 1
if self.cmp(heap[p], heap[c]) > 0:
self.swap(heap, p, c)
else: break
p = c
c = 2 * p + 1
head = ListNode(0)
travel = head
while heap[0] != None:
temp = ListNode(heap[0].val)
travel.next = temp
travel = temp
if heap[0].next == None:
heap[0] = heap[hi - 1]
hi -= 1
if hi == 0: break
else:
heap[0].val = heap[0].next.val
heap[0].next = heap[0].next.next
p = 0
c = 2 * p + 1
while c < hi:
if c + 1 < hi and self.cmp(heap[c + 1], heap[c]) < 0:
c += 1
if self.cmp(heap[p], heap[c]) > 0:
self.swap(heap, p, c)
else: break
p = c
c = 2 * p + 1
return head.next
if __name__ == "__main__":
ls = [convertArrayToListNode([1, 4, 9, 13]),
convertArrayToListNode([2, 6, 10, 14]),
convertArrayToListNode([3, 7, 11, 15]),
convertArrayToListNode([4, 8, 12, 16])]
a = Solution().mergeKLists(ls)
printListNode(a)