LeetCode023 Merge k Sorted Lists

来源:互联网 发布:协和医院app挂号知乎 编辑:程序博客网 时间:2024/06/16 03:54

详细见: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;}}}


C Solution: github
/*    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;}


Python Solution: github

#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)





0 0
原创粉丝点击