LeetCode 23. Merge k Sorted Lists(合并k个有序单链表)

时间:2021-11-26 19:47:05

题目描述:

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

分析:
    题意:给定k个有序单链表,把他们合并成为一个有序单链表并返回。
    思路:这道题是LeetCode 21的进化版本。看到这道题,脑海里首先联想到的是归并排序(Merge Sort):如果我们把k个单链表看成是k个有序子段数组,那么接下来就是对每两个有序数组进行合并(Merge)的过程了。
    也就是说,LeetCode 23对应单链表的归并排序,而LeetCode 21对应单链表的归并排序中的合并过程!
    假设k个单链表中,平均每个单链表包含n个结点,那么平均时间复杂度为O(nlog(k))。

代码:

#include <bits/stdc++.h>

using namespace std;

struct ListNode{
	int val;
	ListNode *next;
	ListNode(int x): val(x), next(NULL){}
};

class Solution {
private: 
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // Exceptional Case: 
		if(!l1){
			return l2;
		}
		if(!l2){
			return l1;
		}
		ListNode *h = new ListNode(-1), *pre = h;
		ListNode *p = l1, *q = l2;
		// merge
		while(p && q){
			if(p->val < q->val){
				pre->next = p;
				pre = p;
				p = p->next;
			}
			else{
				pre->next = q;
				pre = q;
				q = q->next;
			}
		}
		// link the rest of l1
		if(p){
			pre->next = p;
		}
		// link the rest of l2
		if(q){
			pre->next = q;
		}
		return h->next;
    }

public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int n = lists.size();
		// Exceptional Case: 
		if(n == 0){
			return NULL;
		}
		if(n == 1){
			return lists[0];
		}
		if(n == 2){
			return mergeTwoLists(lists[0], lists[1]);
		}
		// divide the lists into two parts
		vector<ListNode*> lists_left, lists_right;
		lists_left.assign(lists.begin(), lists.begin() + n / 2);
		lists_right.assign(lists.begin() + n / 2, lists.end());
		// Divide-And-Conquer
		ListNode *left = mergeKLists(lists_left);
		ListNode *right = mergeKLists(lists_right);
		return mergeTwoLists(left, right);
    }
};