1. 题目

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

2. 思路

第一反应是采用败者树的merge模式,但是败者树的数据结构也就在大二时学过,早忘了细节,实现麻烦。模拟了一下,每次merge最小的两个链,但是选链是每次排序后选择的,有一个case是每条链都是一个字符,链很多,于是超时了。起始也可以改进一下将排序改为链表结构的插入排序。更好的是改为Heap结构。没有实施。
改为两路merge的方式,通过递归实现很简单。

3. 代码

耗时:26ms

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 
struct List {
    ListNode* head;
    int len;
};

bool ListCmp(List& l1, List& l2) {
    return l1.len > l2.len;
}

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return mergeKListsTwoRoad(lists, 0, lists.size());
        ListNode* ret = NULL;
        
        
        return ret;
    }

/////////Two Road Merge///////////
    ListNode* mergeKListsTwoRoad(vector<ListNode*>& lists, int s, int e) {
        if (s >= e) return NULL;
        if (s + 1 == e) return lists[s];
        int sz = e - s;
        int sz1 = sz / 2;
        ListNode* p1 = mergeKListsTwoRoad(lists, s, s + sz1);
        ListNode* p2 = mergeKListsTwoRoad(lists, s + sz1, e);
        return mergeList(p1, p2);
    }
    
    ListNode* mergeList(ListNode* p1, ListNode* p2) {
        if (p1 == NULL) return p2;
        if (p2 == NULL) return p1;
        ListNode* head = NULL;
        if (p1->val < p2->val) {
            head = p1;
            p1 = p1->next;
        } else {
            head = p2;
            p2 = p2->next;
        }
        ListNode* p = head;
        while (p1 != NULL && p2 != NULL) {
            if (p1->val < p2->val) {
                p->next = p1;
                p1 = p1->next;
            } else {
                p->next = p2;
                p2 = p2->next;
            }
            p = p->next;
        }
        if (p1 != NULL) {
            p->next = p1;
        }
        if (p2 != NULL) {
            p->next = p2;
        }
        return head;
    }


////////////////////////////////////////version of Time Limit Exceeded ////////////////////////////////////
    ListNode* mergeKLists_pitch2ShorterEach(vector<ListNode*>& lists) {
        vector<List> ls;
        for (int i = 0; i < lists.size(); i++) {
            List l;
            l.head = lists[i];
            l.len = length(l.head);
            ls.push_back(l);
        }
        sort(ls.begin(), ls.end(), ListCmp);
        List lr = mergeKLists(ls);
        return lr.head;
    }
    
    List mergeKLists(vector<List>& ls) {
        List l;
        if (ls.size() == 0) return l;
        if (ls.size() == 1) return ls[0];
        while (ls.size() > 1) {
            List l1 = ls.back();
            ls.pop_back();
            List l2 = ls.back();
            ls.pop_back();
            l = mergeList(l1, l2);
            ls.push_back(l);
            int i = ls.size() - 2;
            for (; i >= 0; i--) {
                List& li = ls[i];
                if (li.len < l.len) {
                    ls[i + 1] = ls[i];
                }
            }
            ls[i] = l;
        }
        return ls[0];
    }
    
    int length(ListNode* p) {
        if (p == NULL) return 0;
        int n = 0;
        while (p != NULL) {
            n++;
            p = p->next;
        }
        return n;
    }
    
    List mergeList(List l1, List l2) {
        if (l1.len == 0) return l2;
        if (l2.len == 0) return l1;
        List r;
        r.len = l1.len + l2.len;
        ListNode* p1 = l1.head;
        ListNode* p2 = l2.head;
        if (p1->val < p2->val) {
            r.head = p1;
            p1 = p1->next;
        } else {
            r.head = p2;
            p2 = p2->next;
        }
        ListNode* p = r.head;
        while (p1 != NULL && p2 != NULL) {
            if (p1->val < p2->val) {
                p->next = p1;
                p1 = p1->next;
            } else {
                p->next = p2;
                p2 = p2->next;
            }
            p = p->next;
        }
        if (p1 != NULL) {
            p->next = p1;
        }
        if (p2 != NULL) {
            p->next = p2;
        }
        return r;
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书


引用和评论

0 条评论