【Leetcode】【Hard】Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
解题思路:
1、先取出k个list的首元素,每个首元素是对应list中的最小元素,组成一个具有k个结点的最小堆;o(k*logk)
2、此时堆顶元素就是所有k个list的最小元素,将其pop出,并用此最小元素所在list上的下一个结点(如果存在)填充堆顶,并执行下滤操作,重新构建堆。o(logk)
3、不断执行第二步,直到堆中元素为0。o(nlogk)
最终时间复杂度为o(nlogk),k表示list的个数,n表示所有list总结点数;
解题方法1:
使用C++ make_heap,push_heap,pop_heap函数;
步骤:
1、新建一个结点preHead,指向最终返回结果链表的首结点;新建一个curNode指针,用于操作新建链表;
2、将每个list的首指针装入一个新建的vector v中,注意判断list不为空;
3、调用make_heap函数将这些首指针构造成堆;需要编写greater比较函数;
4、循环操作,只要v不为空:
(1)取出堆顶,放入新建链表的末端;
(2)pop_heap,交换当前堆首尾元素,并下滤首元素;
(3)pop_back,删除v最后一个元素(当前最小元素);
(4)push_back,将当前最小元素的下一个元素加入堆尾;
(5)push_heap,对堆尾元素进行上滤;
5、返回preHead->next;
代码:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* mergeKLists(vector<ListNode*>& lists) { //make_heap 12 ListNode prehead(0); 13 ListNode *curNode = &prehead; 14 vector<ListNode*> v; 15 for(int i = 0; i < lists.size(); i++){ 16 if (lists[i]) 17 v.push_back(lists[i]); 18 } 19 make_heap(v.begin(), v.end(), heapComp); //vector -> heap data strcture 20 21 while(v.size() > 0){ 22 curNode->next = v.front(); 23 pop_heap(v.begin(), v.end(), heapComp); 24 v.pop_back(); 25 curNode = curNode->next; 26 if(curNode->next) { 27 v.push_back(curNode->next); 28 push_heap(v.begin(), v.end(), heapComp); 29 } 30 } 31 32 return prehead.next; 33 } 34 35 static bool heapComp(ListNode* a, ListNode* b) { 36 return a->val > b->val; 37 } 38 };
解题方法2:
使用C++ priority_queue 构建最小堆;
步骤和上述基本一致;
代码
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 struct cmp { 12 bool operator()(const ListNode *n1, const ListNode *n2) { 13 return n1->val > n2->val; 14 } 15 }; 16 17 ListNode *mergeKLists(vector<ListNode *> &lists) { 18 priority_queue<ListNode*, vector<ListNode *>, cmp > heap; 19 ListNode pre_head(0); 20 ListNode *curNode = &pre_head; 21 for (int i = 0; i < lists.size(); i++) { 22 if (lists[i]) 23 heap.push(lists[i]); 24 } 25 26 while (!heap.empty()){ 27 curNode->next = heap.top(); 28 heap.pop(); 29 curNode = curNode->next; 30 if (curNode->next) 31 heap.push(curNode->next); 32 } 33 34 return pre_head.next; 35 } 36 };