合并排序

LeetCode 23 合并K个排序链表

喜你入骨 提交于 2020-02-09 03:08:26
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 输入:1->4->5, 1->3->4, 2->6 输出:1->1->2->3->4->4->5->6 python3: class Solution: def mergeKLists(self, lists: List[ListNode]) -> ListNode: if not lists:return n = len(lists) return self.merge(lists, 0, n - 1) def merge(self, lists, left, right): if left == right: return lists[left] mid = left + (right - left) // 2 l1 = self.merge(lists, left, mid) l2 = self.merge(lists, mid + 1, right) return self.mergeTwoLists(l1, l2) def mergeTwoLists(self, l1, l2): if not l1:return l2 if not l2:return l1 if l1.val < l2.val: l1.next = self.mergeTwoLists(l1.next, l2) return l1

归并排序

醉酒当歌 提交于 2020-02-08 23:20:19
基本思想 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 C++代码 # include <iostream> using namespace std ; void merge ( int arr [ ] , int l , int r , int m ) { int help [ r - l + 1 ] ; int i = 0 ; int p1 = l ; int p2 = m + 1 ; while ( p1 <= m && p2 <= r ) { help [ i ++ ] = arr [ p1 ] < arr [ p2 ] ? arr [ p1 ++ ] : arr [ p2 ++ ] ; } while ( p1 <= m ) { help [ i ++ ] = arr [ p1 ++ ] ; } while ( p2 <= r ) { help [ i ++ ] = arr [ p2 ++ ] ; } for ( i = 0 ; i < r - l + 1 ; i ++ ) { arr

Leedcode编程题23: 合并K个排序链表----C++实现

一曲冷凌霜 提交于 2020-02-04 11:26:38
目的 旨在记录在Leedcode网上刷题的过程,记录心得。 题目 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 思路 参考大神的思路,实现的代码。 1)获取到所有的链表元素放在vector中; 2)将vector从小到大排序; 3)根据排好序的vector元素来创建链表,所得链表即为结果。 代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { vector<int> templist; for(auto li:lists){ while(li){ templist.push_back(li->val); li = li->next; } } int numsize = templist.size(); if(numsize==0) return NULL;

【leetcode】23.合并K个排序链表

▼魔方 西西 提交于 2020-02-04 09:15:22
https://leetcode-cn.com/problems/merge-k-sorted-lists/ 这道题的前置题目是合并两个排序链表 https://leetcode-cn.com/problems/merge-two-sorted-lists/ 暴力法 将所有链表合并后排序 时间复杂度O(NlogN) N= 总节点数量 空间复杂度O(N) 归并 基于合并两个排序链表,我们可以做到循环依次合并两个链表,将问题转换为合并两个排序链表k-1次; 由于每次合并前后,被合并链表和所得链表的结构(有序性)不变,因此可以采用分治、归并的方式,对每两个链表进行合并,再将合并后的结果继续按此逻辑每两个相合并 时间复杂度:O(NlogK) 举例图示: 0 1 2 3 4 5 6 01 23 45 6 0123 456 0123456 我的代码: /** * 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.length == 1)

归并排序

不羁的心 提交于 2020-02-01 01:15:46
算法核心: 大 序 列 递 归 到 小 序 列 , 进 行 排 序 然 后 合 并 \color{red}{大序列递归到小序列,进行排序然后合并} 大 序 列 递 归 到 小 序 列 , 进 行 排 序 然 后 合 并 该 算 法 的 核 心 步 骤 在 于 — — 合 并 ! \color{red}{该算法的核心步骤在于——合并!} 该 算 法 的 核 心 步 骤 在 于 — — 合 并 ! 合 并 操 作 : \color{green}{合并操作:} 合 并 操 作 : mark1 mark2分别用来标记两个子段 抓 住 子 段 已 经 排 序 的 特 点 \color{red}{抓住子段已经排序的特点} 抓 住 子 段 已 经 排 序 的 特 点 每次把mark1 和mark2 中更小的放进去,放完即合并完毕~ void G ( int * head , int * temp , int start , int end ) { //head 为待排序序列 temp为暂存数组 //start和end 表示从start到end之间进行排序 int mark1 , mark2 ; //两子段合并时用的的标记变量 if ( start + 1 == end ) { //递归出口 if ( head [ start ] > head [ end ] ) { int temp =

排序算法汇总(二)

心已入冬 提交于 2020-01-29 03:16:20
我们继续接着插入排序法往下聊。 直接插入排序法的时间复杂度问题 插入排序法(或者叫做直接插入排序法)的原理很简单,也很自然,而且也是后面很多排序法的基础,是不得不会的。它的思想是,每一次将待排序的数据插入到已排好顺序的数组中去。所以一开始,任何一个数据都认为是已排好序的。也就是数组的首元素A[0],设数组长度为n,那么第一次插入是从A[1]开始的,先将A[0]赋值给临时变量key.这是一个临时保存待插入数据的新内存空间,防止数据丢失的,而将A[0]赋值给A[1].key与A[0]比较,若大,则将key赋值给A[1],否则将key赋值给A[0].如此就完成了A[1]的插入操作。这是完全可行的。如果现在是A[j] (j<n)要插入,那么一定是A[:j]已经排好序了,而插入A[j]也是要将它赋值给key,将A[j-1]赋值给A[j],相当于数据后移,先后移,再进行比较,若key大,则key赋值给A[j],否则与A[j-1]比较,这里涉及到一个迭代过程,用i标记前j个元素的下标,将j当做一个常数,i递减。只有当i<0或者key大于等于某个A[i] 时循环才会退出。将key的值赋值给A[i+1],操作完成。 最后,由于数组长度时有限的,当k遍历到n时,整个插入排序的算法结束。下面是算法导论中提供的伪码: 插入排序法最坏和平均情况下时间复杂度都是O(n^2),最好情况下时间复杂度为O(n)

LeedCode_合并K个排序链表

纵饮孤独 提交于 2020-01-29 02:56:28
LeedCode_合并K个排序链表 题目说明 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 链接: https://leetcode-cn.com/problems/merge-k-sorted-lists 分析:提高效率的方法,将链表中的数据存储到数组中,在数组中排序,在进行重新组链。 ListNode * mergeKLists ( vector < ListNode * > & lists ) { ListNode * res ; int n = lists . size ( ) ; if ( n == 0 ) { return NULL ; } if ( n == 1 ) { return lists [ 0 ] ; } vector < int > nums ; for ( int i = 0 ; i < n ; i ++ ) { ListNode * p = lists [ i ] ; while ( p != NULL ) { nums . push_back ( p - > val ) ; p = p - > next ; } } if ( nums . size ( ) == 0 ) { return NULL ; //针对

合并两个排序好的数组

浪子不回头ぞ 提交于 2020-01-27 09:13:53
/** * 合并两个排序好的数组 * @param arr1 * @param arr2 * @param n1 * @param n2 * @param arr3 */ public static void mergeArrays ( int [ ] arr1 , int [ ] arr2 , int n1 , int n2 , int [ ] arr3 ) { int i = 0 , j = 0 , k = 0 ; // Traverse both array while ( i < n1 && j < n2 ) { // Check if current element of first // array is smaller than current element // of second array. If yes, store first // array element and increment first array // index. Otherwise do same with second array if ( arr1 [ i ] < arr2 [ j ] ) arr3 [ k ++ ] = arr1 [ i ++ ] ; else arr3 [ k ++ ] = arr2 [ j ++ ] ; } // Store remaining elements

ACM寒假集训Day-1 入门知识

吃可爱长大的小学妹 提交于 2020-01-26 13:06:00
  这篇以及接下来的几篇博客,会记录我在寒假集训中做到的题的一些想法和思路,一来帮助我更好的进行知识架构,二来可以让我理清思路并更好的掌握相关知识点; A-跳石头 一年一度“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。 为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。 输入格式 输入第一行包含三个整数 L , N , M ,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。 接下来 N 行,每行一个整数,第 i 行的整数 Di(0 < Di < L) D i ( 0 < D i < L ) 表示第 i 块岩石与 起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。 输出格式 输出只包含一个整数,即最短跳跃距离的最大值。 数据范围 对于 2 0% 的数据, 0 ≤ M ≤ N ≤ 1 0。 对于 5 0% 的数据, 0 ≤ M ≤ N ≤ 1 0 0。 对于 1 0 0% 的数据, 0

归并排序mergeSort以及小和问题

时光怂恿深爱的人放手 提交于 2020-01-26 03:23:49
归并排序 时间复杂度O(N*logN),额外空间复杂度O(N),实现可以做到稳定性 #include <cstdio> #include <cstdlib> void merge(int A[], int L, int mid, int R)//两个数组的合并过程,其中要注意的是要合并的两个数组分别一定是有序的 { int i = L, j = mid + 1, k = 0; int *help = (int*)malloc(sizeof(int)*(R - L + 1));//辅助数组 while (i <= mid&&j <= R) { if (A[i] < A[j]) //那边数组数值小放入辅助数组help当中 { help[k++] = A[i++]; } else { help[k++] = A[j++]; } } while (i <= mid)//其余两个while只会实现一个,那个数组没有放入help数组当中,循环放入 { help[k++] = A[i++]; } while (j <= R) { help[k++] = A[j++]; } for (int i = 0; i < k; i++)//最后将辅助数组help当中的数值放入到当前A[]数组的当前排序区域 { A[L + i] = help[i]; } } void sortprosess(int A[]