23-Merge k Sorted Lists
来源:互联网 发布:云计算服务级别sla 编辑:程序博客网 时间:2024/06/06 05:01
难度:hard
分类:divide and conquer
1.题目描述
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
2.算法
刚开始的时候直接尝试像归并排序一样,将排好序的数组两两合并,但是对于指针链表的排序容易出错。所以,最后采用的算法是:
(1)直接将所有排序好的数组放到一个数组中,
(2)使用上一篇博客的归并算法对合并后的数组进行排序,
(3)将排序好的数组重新生成一个链表并返回头节点。
3.代码实现
(leetcode上面只需要提交类,此处代码包含自己的测试)
// 使用归并排序实现 #include <iostream>#include <vector>using namespace std;struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {}};class Solution {public: ListNode* mergeKLists(vector<ListNode*>& lists) { int arr[10000]; int len = lists.size(); int index = 0; // all lists into one array for (int i = 0; i < len; ++i) { ListNode* node = lists[i]; while (node != NULL) { arr[index++] = node->val; node = node->next; } } int n = index; // sort the array mergeSort(arr, 0, n - 1); // change array into a single list ListNode* temp = new ListNode(0); ListNode* head = temp; for (int i = 0; i < n; ++i) { temp->next = new ListNode(arr[i]); temp = temp->next; } return head->next; } void mergeSort(int* array, int min, int max) { // 注意结束条件的判断 if (min >= max) return; int mid = (min + max)/2; // 递归,时间复杂度为O(nlogn) mergeSort(array, min, mid); mergeSort(array, mid + 1, max); combineSub(array, min, mid, max); } int temp[10000]; void combineSub(int* array, int min, int mid, int max) { // 因为两个子数组已经是排序了的,所以只需要不断地比较第一个数, // 然后往后移动直到将所有的数字放到一个总的数组里面即可 int i = min, j = mid + 1, index = min; while (i <= mid && j <= max) { if (array[i] < array[j]) { temp[index++] = array[i++]; } else if (array[i] > array[j]) { temp[index++] = array[j++]; } else { temp[index++] = array[i++]; temp[index++] = array[j++]; } } while (i <= mid) { temp[index++] = array[i++]; } while (j <= max) { temp[index++] = array[j++]; } for (int i = min; i <= max; ++i) { array[i] = temp[i]; } }};int main() { Solution solution; vector<ListNode*> lists; int m, n, value; ListNode* head1 = NULL, *head2 = NULL; ListNode* temp1 = NULL, *temp2 = NULL; head1 = temp1; head2 = temp2; cin >> m >> n; for (int i = 0; i < m; ++i) { cin >> value; if (i == 0) { temp1 = new ListNode(value); head1 = temp1; } else { temp1->next = new ListNode(value); temp1 = temp1->next; } if (i == 1) { head1->next = temp1; } } for (int i = 0; i < n; ++i) { cin >> value; if (i == 0) { temp2 = new ListNode(value); head2 = temp2; } else { temp2->next = new ListNode(value); temp2 = temp2->next; } if (i == 1) { head2->next = temp2; } } lists.push_back(head1); lists.push_back(head2); ListNode* head = solution.mergeKLists(lists); while (head != NULL) { cout << head->val << " "; head = head->next; } cout << endl; return 0;}
4.小结
在实现的过程中,要特别注意指针部分,容易出错。再将数组中的数字转换为链表的时候,因为temp不断地往后移动,所以需要将头节点保存,但是注意不能仅仅复制head=temp,还需要保证head->next = temp->next
// change array into a single listListNode* temp = new ListNode(0);ListNode* head = temp;for (int i = 0; i < n; ++i) { temp->next = new ListNode(arr[i]); temp = temp->next;}return head->next;
5.时间复杂度
在将链表转换为数组和将数组转换为链表的两个过程中,时间都是O(n),而对数组进行排序的时候,采用的是归并排序,时间复杂度是O(nlogn),所以总的时间复杂度是O(nlogn).
阅读全文
0 0
- 23Merge k Sorted Lists
- #23 Merge k Sorted Lists
- 23Merge k Sorted Lists
- 【23】Merge k Sorted Lists
- 23-Merge k Sorted Lists
- 23 Merge k Sorted Lists
- Merge K Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge K Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- Merge k Sorted Lists
- 数据分析经验总结(非专业分析人员)
- Java NIO (一)
- BZOJ2005:能量采集(Mobius反演)
- RecyclerView中使用CheckBox出现勾选混乱的解决方案
- 排序算法之直接插入排序
- 23-Merge k Sorted Lists
- rocket mq Logappender示例——支持log4j等
- mybatis
- 【JEECG_3.7.1】Online树控件的使用
- Java基础(八) -------- UML图
- 运维必须要懂的MySQL主从复制原理
- Android activity相互跳转后台出现两个页面的坑
- 微信小程序使用Socket
- spherface bug