题意:

给一堆已排序链表,合并成一个已排序链表
试了几个方法,最高的大概Runtime排行才71%,不过不知道这个runtime为什么每次都不一样,有的时候能到99%。。。还是我菜啊。

思路1:

就是和之前两个链表合并的思想一样,每次找所有链表里最大的头结点,移动。

ListNode* mergeKLists1(vector<ListNode*>& lists) {//19%
	vector<int> num;
	ListNode *res=NULL, *temp=NULL,*min_list;
	int sz = lists.size(), min_a,min_b;
	for (int i = 0; i < sz; ++i) {
		if (!lists[i]) {
			lists.erase(lists.begin() + i);
			--i;
			--sz;
		}
	}
	if (sz == 0)
		return NULL;
	for (int i = 0; i < sz; ++i)
		num.push_back(i);
	while (sz>1) {
		min_a = INT_MAX;
		for (int i = 0; i < sz; ++i) {
			if (min_a > lists[num[i]]->val) {
				min_list = lists[num[i]];
				min_a = min_list->val;
				min_b = i;
			}
		}
		if (!temp) {
			res = temp = min_list;
		}
		else {
			res->next = min_list;
			res = res->next;
		}
		lists[num[min_b]] = lists[num[min_b]]->next;
		if (!lists[num[min_b]]) { 
			num.erase(num.begin() + min_b); 
			sz--;
		}
	}
	if (res)
		res->next = lists[num[0]];
	else
		return lists[0];
	return temp;
}

思路2:

在思路1的基础上使用二分法优化

ListNode* MergeList(ListNode* a, ListNode*b) {
	if (!a) return b;
	if (!b) return a;
	if (a->val > b->val) swap(a, b);
	ListNode *res = a, *temp = a;
	a = a->next;
	while (a&&b) {
		if (a->val > b->val) {
			temp->next = b;
			temp = temp->next;
			b = b->next;
		}
		else {
			temp->next = a;
			temp = temp->next;
			a = a->next;
		}
	}
	if (a)
		temp->next = a;
	if (b)
		temp->next = b;
	return res;
}


ListNode* mergeKLists2(vector<ListNode*>& lists) {//52.59%
	int sz = lists.size();
	if (sz == 2)
		return MergeList(lists[0], lists[1]);
	if (sz == 1)
		return lists[0];
	if (sz == 0)
		return NULL;
	vector<ListNode*> L(lists.begin(), lists.begin() + sz / 2);
	vector<ListNode*> R(lists.begin() + sz / 2, lists.end());
	return MergeList(mergeKLists2(L), mergeKLists2(R));
}

思路三:

在1的基础上使用堆进行优化,将每个链表的头结点塞入大顶堆,取堆顶后连接在总链表后面再将取出结点的下一结点放入堆中。重复上述操作

ListNode* mergeKLists3(vector<ListNode*>& lists) {
	priority_queue< ListNode*, vector<ListNode*>, greater<int>> pq;
	for (auto l : lists)
		if (l)
			pq.push(l);
	ListNode *node, *head;
	head = NULL;
	while (!pq.empty()) {
		node = pq.top();
		pq.pop();
		if (!head)
			head = node;
		if (node->next)
			pq.push(node->next);
		node->next = pq.empty() ? NULL : pq.top;
	}
	return head;
}