LeetCode 之 Merge Two / k Sorted Lists — C/C++ 實現

Merge Two Sorted Lists

 

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

將兩個有序鏈表合併並返回新的鏈表。新鏈表是由原鏈表的節點鏈接組成。

分析:

維護一個新的頭指針,分別從 L1 和 L2 的頭結點開始向後比較,將值小的節點加入新鏈表,然後指針後移,另一個不變,重複此過程直到兩個鏈表合併完。

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode *head = NULL, *pre = NULL;
    
    if(!l2) //l2爲空指針,直接返回l1
    {
        return l1;
    }
    if(!l1)//l2不爲空,l1爲空
    {
        l1 = l2;
        return l1;
    }

    while(l1 || l2)
    {
        if(!l1) /* l1合併完成,l2沒完成 */
        {
            pre->next = l2;
            pre = pre->next;
            l2 = l2->next;
            continue;
        }
        if(!l2)/* l2合併完成,l1沒有完成 */
        {
            pre->next = l1;
            pre = pre->next;
            l1 = l1->next;
            continue;
        }
        
        /* l1 l2 都沒合併完*/
        if(NULL == head)/*第一個節點*/
        {
            if(l1->val <= l2->val) /*l1小,加入新鏈表*/
            {
                head = pre = l1;
                l1 = l1->next;
                if(pre->val == l2->val)/*l1 l2 相等,都加入新鏈表*/
                {
                    pre->next = l2;
                    pre = pre->next;
                    l2 = l2->next;
                }
            }
            else/*l2 小,加入新鏈表*/
            {
                head = pre = l2;
                l2 = l2->next;
            }
        }
        else
        {
            if(l1->val <= l2->val) /*l1小,加入新鏈表*/
            {
                pre->next = l1;
                l1 = l1->next;
                pre = pre->next;
                if(pre->val == l2->val)/*l1 l2 相等,都加入新鏈表*/
                {
                    pre->next = l2;
                    pre = pre->next;
                    l2 = l2->next;
                }
            }
            else/*l2 小,加入新鏈表*/
            {
                pre->next = l2;
                pre = pre->next;
                l2 = l2->next;
            }
        }
    }
    
    return head;
}


Merge k Sorted Lists

 

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

將 k 個有序鏈表合併成一個新鏈表並返回,分析和描述複雜度。

分析:

歸併排序。對每個有序鏈表看成一個整體,然後和其他的鏈表進行歸併排序。時間複雜度爲 O(nlogn).

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()) //空
        {
            return NULL;
        }
        if(lists.size() == 1)
        {
            return lists[0];
        }
        
        //歸併排序
        return mergeList(lists);
    }
    
    //劃分   
    ListNode* mergeList(vector<ListNode*>& lists){
        int listsSize = lists.size();
        
        if(1 == listsSize)
        {
            return lists[0];
        }
        
        vector<ListNode*> vleft(lists.begin(), (lists.begin() + (listsSize-1)/2 + 1));
        vector<ListNode*> vright((lists.begin() + (listsSize-1)/2 + 1), lists.end());
        ListNode *left = mergeList(vleft);//左半部分歸併排序
        ListNode *right = mergeList(vright);//右半部分歸併排序
        return merge2Lists(left, right);
    }
    
    //合併
    ListNode* merge2Lists(ListNode* left, ListNode* right){
        if(!left && !right)
        {
            return NULL;
        }
        
        ListNode *tempHead = new ListNode(0), *pre = tempHead; //新建頭結點
        ListNode *head = left;
        ListNode *plist = right;

        while(head || plist)
        {
            if(!head) //head合併完,lists[i]沒有完成
            {
                pre->next = plist;
                pre = pre->next;
                plist = plist->next;
                
                continue;
            }
            if(!plist)//lists[i]合併完,head沒有完成
            {
                pre->next = head;
                pre = pre->next;
                head = head->next;
                
                continue;
            }
            
            if(head->val <= plist->val)//head <= lists[i]
            {
                pre->next = head;
                pre = pre->next;
                head = head->next;
                
                if(pre->val == plist->val)//注意:此處是 pre->val, head已經指向下個節點
                {
                    pre->next = plist;
                    pre = pre->next;
                    plist = plist->next;
                }
            }
            else //head > lists[i]
            {
                pre->next = plist;
                pre = pre->next;
                plist = plist->next;
            }
        }
        
        head = tempHead->next;
        delete tempHead;
        
        return head; 
    }
};

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