LeetCode第23题之Merge k Sorted Lists
来源:互联网 发布:64码高清网络电视官方 编辑:程序博客网 时间:2024/06/16 05:48
楼主是参考:http://www.cnblogs.com/skysand/p/4300711.html,感觉这篇博客写得挺好的。
C++代码:
#include <vector>#include <iostream>#include <algorithm>using namespace std;/** * Definition for singly-linked list. */ struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} };class Solution {public: // 小顶堆,以第i个元素为根建立小顶堆 //位置从1开始,取元素时记得-1 // 自顶向下 void minHeap(vector<ListNode *> &heap, int i) { int l = i*2; int r = i*2+1; int least = i; //如果左孩子存在,且左孩子小于父节点 if (l-1<heap.size() && heap[l-1]->val < heap[least-1]->val) { least = l; } if (r-1 < heap.size() && heap[r-1]->val < heap[least-1]->val) { least = r; } //如果父节点的值不是最小 if (least != i) { swap(heap[i-1], heap[least-1]); minHeap(heap, least); } } // 建立小顶堆 // 自低向上 void makeHeap(vector<ListNode *> &heap) { int sz = heap.size(); for (int i=sz/2;i>0;--i) { minHeap(heap,i); } } //弹出堆顶的元素 ListNode *popHeap(vector<ListNode *>& heap) { int sz = heap.size(); if (sz > 0) { swap(heap[0], heap[sz-1]); } ListNode * p = heap.back(); heap.pop_back(); minHeap(heap,1); return p; } // 在小顶堆中插入一个元素 // 自低向上 void pushHeap(vector<ListNode *> &heap, ListNode *p) { heap.push_back(p); int child = heap.size(); int parent = child/2; while (parent && heap[child-1]->val < heap[parent-1]->val) { swap(heap[child-1], heap[parent-1]); child = parent; parent /= 2; } } ListNode* mergeKLists(vector<ListNode*>& lists) { // 使用堆排序, // 1. 选出每个链表的头来插入小顶堆中, // 2. 再把堆顶接入合并链表中, // 3. 被选出的指针后移再加入小顶堆中,回到2 // 4. 最后所有链表都为空时,返回合并链表的头指针 int sz = lists.size(); if (0 == sz) return NULL; vector<ListNode *> heap; // 1. 选出每个链表的头来插入小顶堆中, for (int i=0;i<sz;++i) { if (lists[i]) heap.push_back(lists[i]); } makeHeap(heap); /*for (int i=0;i<heap.size();++i) { cout<<heap[i]->val<<'\t'; } cout<<endl;*/ // 2. 再把堆顶接入合并链表中, ListNode head(-1); ListNode *p = &head; ListNode *tmp = NULL; while(!heap.empty()) { tmp = popHeap(heap); p->next = tmp; p = p->next; // 3. 被选出的指针后移再加入小顶堆中,回到2 if (tmp->next) { pushHeap(heap, tmp->next); } } // 4. 最后所有链表都为空时,返回合并链表的头指针 return head->next; }};void print_list(vector<ListNode *> lists){ for (int i=0;i<lists.size();++i) { ListNode *p = lists[i]; while(p) { cout<<p->val<<'\t'; p = p->next; } cout<<endl; }}int main(){ Solution s; vector<ListNode *> lists; for (int i=0;i<4;++i) { ListNode *head,*p; head = NULL; for (int j=5;j>i;--j) { p = head; head = new ListNode(j); head->next = p; // head = p; } lists.push_back(head); }// print_list(lists); ListNode * res = s.mergeKLists(lists); while(res) { cout<<res->val<<'\t'; res = res->next; } cout<<endl; return 0;}
**优化代码:
后来想到既然堆每次加入一个元素的时候都要调整堆顶,那么每次把要添加的元素换到堆顶再调整就不用写pushHeap的函数了,当要添加的元素为空时,相当于执行popHeap函数,因此可以简化代码:**
#include <vector>#include <iostream>#include <algorithm>using namespace std;/** * Definition for singly-linked list. */ struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} };class Solution {public: // 小顶堆,以第i个元素为根建立小顶堆 //位置从1开始,取元素时记得-1 // 自顶向下 void minHeap(vector<ListNode *> &heap, int i) { int l = i*2; int r = i*2+1; int least = i; //如果左孩子存在,且左孩子小于父节点 if (l-1<heap.size() && heap[l-1]->val < heap[least-1]->val) { least = l; } if (r-1 < heap.size() && heap[r-1]->val < heap[least-1]->val) { least = r; } //如果父节点的值不是最小 if (least != i) { swap(heap[i-1], heap[least-1]); minHeap(heap, least); } } void makeHeap(vector<ListNode *> &heap) { int sz = heap.size(); for (int i=sz/2;i>0;--i) { minHeap(heap,i); } } ListNode* mergeKLists(vector<ListNode*>& lists) { int sz = lists.size(); if (0 == sz) return NULL; vector<ListNode *> heap; //将每条链表的首节点的指针加入到heap堆中 for (int i=0;i<sz;++i) { if (lists[i]) heap.push_back(lists[i]); } makeHeap(heap); /*for (int i=0;i<heap.size();++i) { cout<<heap[i]->val<<'\t'; } cout<<endl;*/ ListNode head(-1); ListNode *p = &head; ListNode *tmp = NULL; while(!heap.empty()) { tmp = heap[0]; p->next = tmp; p = tmp; if (tmp->next) { heap[0] = tmp->next; } else { swap(heap[0],heap[heap.size()-1]); heap.pop_back(); } minHeap(heap,1); } return head->next; }};void print_list(vector<ListNode *> lists){ for (int i=0;i<lists.size();++i) { ListNode *p = lists[i]; while(p) { cout<<p->val<<'\t'; p = p->next; } cout<<endl; }}int main(){ Solution s; vector<ListNode *> lists; for (int i=0;i<4;++i) { ListNode *head,*p; head = NULL; for (int j=5;j>i;--j) { p = head; head = new ListNode(j); head->next = p; // head = p; } lists.push_back(head); }// print_list(lists); ListNode * res = s.mergeKLists(lists); while(res) { cout<<res->val<<'\t'; res = res->next; } cout<<endl; return 0;}
0 0
- LeetCode第23题之Merge k Sorted Lists
- leetcode 第23题 Merge k Sorted Lists
- leetcode第23题——***Merge k Sorted Lists
- LeetCode之23---Merge k Sorted Lists
- 第23题: Merge k Sorted Lists
- LeetCode之Merge k Sorted Lists
- LeetCode之Merge k Sorted Lists
- LeetCode之Merge K Sorted Lists
- leetcode之Merge k Sorted Lists
- leetcode 之 Merge k Sorted Lists
- LeetCode之Merge k Sorted Lists
- 【Leetcode】之Merge k Sorted Lists
- leetcode之Merge k Sorted Lists
- leetcode 刷题之路 93 Merge k Sorted Lists
- LeetCode(23)Merge K Sorted Lists
- [leetcode 23] Merge k Sorted Lists
- [leetcode]23 Merge k Sorted Lists
- [#23 leetcode]Merge k Sorted Lists
- UESTC 490 Swap Game (特殊的求解逆序对数)
- 算法--动态规划
- 安卓实现随时获取Context(来自《第一行代码》)
- 二叉树--trie树
- Android自定义view
- LeetCode第23题之Merge k Sorted Lists
- Ajax解决IE浏览器兼容问题
- hdu5698瞬间移动+杨辉三角+LUCAS
- 解决tomcat启动Socket监听端口死循环被hold问题
- 2、.getcom.mchange.v2.c3p0.impl.NewProxyConnection cannot becast to com.mysql.jdbc.Connection
- A Two-Stage Ensemble of Diverse Models for Advertisement Ranking in KDD Cup 2012
- Java_【第一个小游戏-单词拼写字母排序】
- Java保留两位小数问题
- 编程之美2.1求二进制数中1的个数及扩展问题Java版