LeetCode 023. Merge k Sorted Lists

本文探讨了合并k个已排序链表的问题,最初使用两两合并的方法导致超时,随后采用堆排序思想优化算法,实现复杂度为O(mn)的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值