LeetCode 023. 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.





一開始的思路是先將兩個鏈表合併,然後每次從剩下的鏈表中取出一個鏈表與之合併。假設共有m條鏈表且每條鏈表長度均爲n,則複雜度爲:

2n+3N+4n+5n+6n+……+mn = (m-1)(m+2)n/2

也即複雜度爲O(n*m^2)

經過驗證發現超時了。因此,修改了思路。借鑑堆排序思想,構建一個小頂堆,每次從堆頂中取一個元素構建鏈表,並加入一個新的元素重新建堆。該思路算法複雜度爲O(mn)

代碼如下:

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

class Solution 
{
public:
	//已知heap_array中除了heap_array[s]外均滿足小頂堆的定義
	//調整heap_array[s]使heap_array成爲一個小頂堆
	void HeapAdjust(vector<ListNode *> & heap_array, int s, int n)
	{
		ListNode * temp = heap_array[s];
		for(int i=2*s; i<=n; i*=2)
		{
			if(i<n && heap_array[i]->val > heap_array[i+1]->val)
				i++;
			if(temp->val <= heap_array[i]->val)
				break;
			heap_array[s] = heap_array[i];
			s = i;
		}
		heap_array[s] = temp;	
	}

    ListNode *mergeKLists(vector<ListNode *> &lists) 
    {
		int num = lists.size();
		int length = 0; //lists中非空鏈表數目
		int i = 0;
		if(!num)
			return NULL;
		//將非空鏈表置於lists前面
		for(i=0; i<num; i++)
		{
			if(lists[i]!=NULL)
			{				
				if(i != length)
					lists[length] = lists[i];					
				length ++;
			}
		}
		if(!length)
			return NULL;
		else if(length == 1)
			return lists[0];
		ListNode * head = new ListNode(0);
		ListNode * travel = head;
		//構建一個數組,建堆並進行堆排序,堆排序,有效數據下標從1開始
		vector <ListNode *> heap_array (length+1);
		
		for(i=1; i<=length; i++)
			heap_array[i] = lists[i-1];
		//建堆
		for(i=length/2; i>0; i--)
			HeapAdjust(heap_array,i,length);
		//取出最小結點,並更新數組

		while(length > 1)
		{
			travel->next = heap_array[1];
			travel = travel->next;
			if(heap_array[1]->next != NULL)
				heap_array[1] = heap_array[1]->next;
			else  //如果某一個鏈表已經完全取盡,則將最後一個鏈表換上,並且length-1
			{
				heap_array[1] = heap_array[length];
				heap_array[length] = NULL;
				length = length -1;	
			}
			HeapAdjust(heap_array,1,length);
		}
		travel->next = heap_array[1];
		travel = head;
		head = head->next;
		delete travel;
		return head;
    }
};


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