Merge k Sorted Lists

一. Merge k Sorted Lists

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

Difficulty:Hard

TIME:16MIN

解法一

我們都知道合併兩個有序的列表,時間複雜度爲O(n) ,但如果是合併k個列表呢?最簡單的做法當然是每次從k個列表中找到符合要求的元素,然後加入新的列表中。

ListNode* mergeKLists(vector<ListNode*>& lists) {
    ListNode *head = NULL;
    ListNode *p = NULL;
    bool loo = true;
    while(loo) {
        loo = false;
        ListNode *tmp;
        int val = INT32_MAX;
        int index;
        for(int i = 0; i < lists.size(); i++) {
            if(lists[i] != NULL && lists[i]->val <= val) {
                val = lists[i]->val;
                tmp = lists[i];
                index = i;
                loo = true;
            }
        }
        if(!loo)
            break;
        if(head == NULL)
            head = tmp;
        if(p != NULL)
            p->next = tmp;
        p = tmp;
        lists[index] = lists[index]->next;
    }
    return head;
}

代碼的時間複雜度爲O(kn) ,其中k 爲要合併的列表個數。

解法二

其實在做的過程中就發現,根本就不需要每次遍歷k個列表尋找符合要求的元素,其實只需要第一次遍歷k個列表就行了,之後只需要遍歷一次列表,就可以獲取符合要求的元素,不過需要最小優先隊列。

時間複雜度爲O(nlogk)

解法三

合併列表,可能就會想到歸併排序,如果合併k個列表,那麼採用歸併的方法,其實也只需要操作logk 次而已,因此時間複雜度是和採用最小優先隊列是一樣的。

ListNode* merge(ListNode *a,ListNode *b) { //合併兩個列表
    ListNode *head = NULL;
    ListNode *p = NULL;
    while(a != NULL || b != NULL) {
        ListNode *tmp = NULL;
        if(b != NULL && (a == NULL || a->val >= b->val)) {
            tmp = b;
            b = b->next;
        }
        else {
            tmp = a;
            a = a->next;
        }
        if(head == NULL)
            head = tmp;
        if(p != NULL)
            p->next = tmp;
        p = tmp;
    }
    return head;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
    lists.push_back(NULL);
    deque<ListNode*> que(lists.begin(), lists.end()); //這裏採用雙端隊列
    while(que.size() > 1) {
        que.push_back(merge(que[0],que[1]));
        que.pop_front();
        que.pop_front();
    }
    return que[0];
}

時間複雜度爲O(nlogk)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章