合并排序

【LeetCode 23】合并K个排序链表

时光怂恿深爱的人放手 提交于 2019-12-04 01:19:45
题目链接 【题解】 会归并排序吧? 就把这K个链表当成是K个数字就好。 然后做归并排序。 因为归并排序的时候本来就会有这么一个过程。 [l..mid]和[mid+1..r]这两段区间都是有序的了已经。 然后再把他们俩合并起来。 合并起来之后把这个链表直接放在这个区间的最左边那个位置就好 上一级的合并要用的时候就直接取这个区间最左边那个链表。 有个人关于时间复杂度的证明说的挺好的贴一下 【代码】 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void merge(vector<ListNode*> &lists,int l,int r){ if (l>=r) return; int mid = (l+r)>>1; merge(lists,l,mid);merge(lists,mid+1,r); ListNode *temp = (ListNode *) malloc(sizeof(ListNode)); temp->next =NULL; ListNode *p = temp; ListNode *p1

23. 合并K个排序链表

纵然是瞬间 提交于 2019-12-03 11:06:26
题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze an d describe its complexity. /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ 方法1: 合并两个链表的扩展,两个两个的合并。 代码: class Solution { public: ListNode *mergeKLists(vector<ListNode *> &lists) { int n = lists.size(); if(n == 0) return nullptr; if(n == 1) return lists[0]; ListNode *ret = lists[0]; for(int i = 1;i<n;i++) ret = mergeTwoLists(ret,lists[i]); return ret; } ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { if(l1 == nullptr)

归并排序

你。 提交于 2019-12-03 10:52:55
   归并排序是一个典型的基于分治的递归算法。它不断地将原数组分成大小相等的两个子数组(可能相差1),最终当划分的子数组大小为1时,将划分的有序子数组组合并成一个更大的有序数组。        算法分析:     分,也就是把原数组划分成两个子数组的过程。     治,它将两个有序数组合并成一个更大的有序数组。   它将数组平均分成两部分:center=(left+right)/2,当数组分的足够小时(数组中只有一个元素时),只有一个元素的数组自然而然地就可以视为是有序的,此时就可以进行合并操作了。因此,上面讲的合并两个有序的子数组,是从只有一个元素的两个字数组开始合并的。   合并后的元素个数:从1->2->4->8->...   举例:   比如初始数组为:[24,13,25,1,2,27,38,15]     1)分成了两个大小相等的子数组:[24,13,25,1],[2,27,38,15]     2)再划分成四个大小相等的子数组:[24,13],[25,1],[2,27],[38,15]     3)此时,left<right还是成立的,再分为:[24],[13],[25],[1],[2],[27],[38],[15]   此时,有8个小数组,每个数组都可以视为有序的数组!每个数组中的left=right,从递归中返回,故开始执行合并(第21行):     merge(

经典排序--归并排序

十年热恋 提交于 2019-12-03 10:10:37
归并排序的原理   归并排序是利用归并的思想实现的排序方法,该方法采用经典的分治策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则是将分的阶段得到的答案修补在一起,即分而治之)。 图解归并排序    下面我们以待排序数组 8,4,5,7,1,3,6,2,9,10为例,以图解的方式讲解归并排序的原理。   (1)分治原理图(由于图片太大,没法截全,我进行了一定压缩,所以看起来有点奇怪...)   从图中可以看出,归并排序是先将数组进行拆分,拆分到剩余一个关键字,这是一个从大到小的过程。然后再进行治理,治理的过程也就是进行合并的过程,合并时会保证左右两边的数组内部各自有序。然后将两个有序的数组合并到一个数组中,且合并后的数组有序。总结就是:递归拆分,回溯合并,合并时左右两个数组内部有序。   (2)递归原理图   在看递归原理图前,我们先看下归并排序的代码,如下所示 1 public class MergeSort { 2 private static int count = 1; 3 public static void main(String[] args) { 4 int[] arr = {8, 4, 5, 7, 1, 3, 6, 2, 9, 10}; 5 int[] temp = new int[arr.length]; 6 split(arr, 0, arr

[LeetCode]23. 合并K个排序链表(优先队列;分治待做)

北慕城南 提交于 2019-12-03 08:23:36
题目 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6] 输出: 1->1->2->3->4->4->5->6 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-k-sorted-lists 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 题解 方法一 优先队列 分别取每个链表的头节点比较,将最小的作为新链表的第一个节点。若这个节点后面还有节点,则将一个节点放入比较的集合。 比较的集合使用优先队列维护(堆实现)。 方法二 分治 todo 代码 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } PriorityQueue<ListNode> queue =

839. 合并两个排序的间隔列表

匿名 (未验证) 提交于 2019-12-03 00:27:02
描述 合并两个已排序的间隔列表,并将其作为一个新的排序列表返回。新的排序列表应该通过拼接两个列表的间隔并按升序排序。 给定列表中的间隔一定不会重叠。 不同列表中的间隔可能会重叠。 是 样例 [(1,2),(3,4)] [(2,3),(5,6)] [(1,4),(5,6)] . 文章来源: 839. 合并两个排序的间隔列表

leetcode 23.合并K个排序链表

巧了我就是萌 提交于 2019-12-02 11:54:01
题目:合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-k-sorted-lists 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解决方案,需要对每个数据进行排序,我们选择构建一个最小堆,将每个元素放入堆中,然后创建一个新的链表,将堆顶元素依次取出,并添加到链表中。 class Solution { public ListNode mergeKLists ( ListNode [ ] lists ) { int len = 0 ; if ( ( len = lists . length ) == 0 || lists == null ) return null ; ListNode preHead = new ListNode ( - 1 ) ; ListNode preNode = preHead ; PriorityQueue < ListNode > queue = new PriorityQueue < > ( len , new Comparator < ListNode > ( ) {

排序算法之合并排序

試著忘記壹切 提交于 2019-12-02 08:08:21
合并排序法 (Merge Sorting) 是外部排序最常使用的排序方法。 主要应用场景是:若数据量太大无法一次完全加载内存, 可使用外部辅助内存来处理排序数据,主要应用在文件排序。 排序方法: 将欲排序的数据分别存在数个文件大小可加载内存的文件中, 再针对各个文件分别使用“内部排序法” 将文件中的数据排序好写回文件。 再对所有已排序好的文件两两合并, 直到所有文件合并成一个文件后, 则数据排序完成。 合并排序 是使用到了分治方法(Divide and Conquer)。   Divide:将原问题分解为若干子问题,其中这些子问题的规模小于原问题的规模。   Conquer:递归地求解子问题,当子问题规模足够小时直接求解。   Merge:将子问题的解合并得到原问题的解。 下面是代码实现部分: class Merge{ public void merge_sort(int arr[], int start, int end) { //当数组长度大于0时,继续进行分割 if(start < end) { //每次分割都是找到中间位置,作为分割点 int m = (start + end) / 2; //分割的前半段,继续进行分割 merge_sort(arr, start, m); //分割的后半段,也继续进行分割。都进行分割的前提是,长度大于0,且还能分割 merge_sort

MapTask工作机制

余生长醉 提交于 2019-12-01 16:20:09
一、MapTask并行度决定机制    二、MapTask的工作机制      (1)Read阶段:     Map Task通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value。   (2)Map阶段:     该节点主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value。   (3)Collect收集阶段:     在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果。在该函数内部,它会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中。   (4)Spill阶段:     即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。    溢写阶段详情:   步骤1:利用快速排序算法对缓存区内的数据进行排序,排序方式是,先按照分区编号partition进行排序,然后按照key进行排序。这样,经过排序后,数据以分区为单位聚集在一起,且同一分区内所有数据按照key有序。    步骤2