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;
    }
};


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