23. 合併K個元素的有序連結串列

關關的刷題日記發表於2018-04-07

合併K個有序連結串列,並且作為一個有序連結串列的形式返回。分析並描述它的複雜度。

思路:每兩個連結串列一合併,每一次規模縮減為原來的一半,直到最後剩兩個連結串列合併為一個連結串列。

複雜度分析: 第一次兩兩合併是進行了k/2次,每次處理2n個值。第二次兩兩合併是進行了k/4次,每次處理4n個值。。。。最後(設第x次)一次兩兩合併,進行了一次合併(k/(2^x)=1,求出x=logk),每次處理 n*k個值。

所以O(n)=nklogk,因為每個連結串列長度可能不一樣,nk就是所有連結串列總長度,因此O(n)=Nlogk(N為k個連結串列總長度)

方法1:用vector迭代來做。

class Solution {
public:
   ListNode* mergeTwo(ListNode* l1, ListNode* l2)
 {
	 if (!l1) return l2;
	 if (!l2) return l1;
	 ListNode *dummy = new ListNode(0), *head=dummy;
	 while (l1 && l2)
	 {
		 if (l1->val <= l2->val)
		 {
			 head->next = l1;
			 l1 = l1->next;
		 }
		 else
		 {
			 head->next = l2;
			 l2 = l2->next;
		 }
		 head = head->next;
	 }
	 if (l1)
		 head->next = l1;
	 if (l2)
		 head->next = l2;
	 return dummy->next;
 }
    
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty())     return nullptr;
        while(lists.size()>1){
            vector<ListNode*> temp;
            for(int i=1; i<lists.size(); i=i+2)
            {
                ListNode *p=mergeTwo(lists[i-1], lists[i]);
                temp.push_back(p);
            }
            if(lists.size()%2==1)  temp.push_back(lists.back());
            lists=temp;
        }
        return lists.back(); 
    }
};

方法2:迭代的部分用遞迴來處理

class Solution {
public:  
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty())
            return nullptr;
        vector<ListNode*> temp;
        for(int i=1; i<lists.size(); i=i+2)
        {
            ListNode *p=mergeTwo(lists[i-1], lists[i]);
            temp.push_back(p);
        }
        if(lists.size()%2==1)
            temp.push_back(lists.back());
        if(temp.size()==1)
            return temp[0];
        else
            return mergeKLists(temp); 
    }
};

方法3:優先佇列來做

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty())     return nullptr;
        queue<ListNode*>re;
        while(!lists.empty()){
            re.push(lists.back());
            lists.pop_back();
        }
        
        while(re.size()>1){
            ListNode* a=re.front();
            re.pop();
            ListNode* b=re.front();
            re.pop();
            re.push(mergeTwo(a, b));
        }
        return re.front(); 
    }
};


相關文章