合并排序

归并排序

狂风中的少年 提交于 2020-01-23 02:59:18
归并排序是一个典型的基于分治的递归算法。它不断地将原数组分成大小相等的两个子数组(可能相差1),最终当划分的子数组大小为1时(即left小于right不成立时) ,将划分的有序子数组合并成一个更大的有序数组。 归并排序思路分析: 归并排序算法有两个基本的操作,一个是分,也就是把原数组划分成两个子数组的过程。另一个是治,它将两个有序数组合并成一个更大的有序数组。 它将数组平均分成两部分: center = (left + right)/2,当数组分得足够小时---数组中只有一个元素时,只有一个元素的数组自然而然地就可以视为是有序的,此时就可以进行合并操作了。因此,上面讲的合并两个有序的子数组,是从 只有一个元素 的两个子数组开始合并的。 合并后的元素个数:从 1-->2-->4-->8...... 比如初始数组:[19,15,37,12,25] 0 1 2 3 4 19 15 37 12 25 第一步:分解 首先将数组拆分成两部分,即19 15 37为一组,12 25为一组,这是第一层,如图所示: 19 15 37 12 25 第二步:分解 将第一步得到的数组继续分解,19 15为一组,37为一组,12为一组,25为一组,这四组是第二层,如图所示: 19 15 37 12 25 第三步:分解 将第二步分解得到的数组再次分解,此时只剩下19 15这一组可以分解,所以继续分解,19为一组

bzoj 泛做

爱⌒轻易说出口 提交于 2020-01-22 23:47:10
3003 这个题是这样的,对序列差分后,每个取反操作就是给两个端点的值取反,然后背包之后再状压就好了 4128 这题棒棒的QAQBSGS 23333 4176 这个杜教筛呃呃呃 大爷链接 3028 我要去学学生成函数 大爷链接 4025 我真TM是智商爆降了,这个东西明显的按时间分治一下就好了,管他什么lct 3498 一位大爷:“将所有点分成两类:度数 < sqrt(m)的和度数 > sqrt(m)的.先求包含第一类点的三元环个数.由于边很少,所以枚举2条边即可.由于一个点的度不超过sqrt(m),所以一条边最多被枚到(sqrt(m))次,最多枚M条边,所以这个操作时O(m sqrt(m))的.再求不包含第一类点的三元环个数.由于每条边贡献2个度,所以二类点的数量是O(sqrt(m))级的.直接枚举三个点,复杂度O((sqrt(m))^3)=O(m sqrt(m))所以算法总的复杂度是O(m*sqrt(m))的.” 5043 先发个 神犇友链 当时只知道暴力,f[i][j]表示第i位剩余j最小的k但是这样j为2^60太大无法忍受,所以可以倒着按位做表示这一位剩余j,一定满足j<=n,这样复杂度降为60n,好棒棒呦 4241 一样看以为莫队结果被怼啦 大爷链接 ,填填坑 2400 这题其实很简单,然而......因为是异或运算,所以每一位独立然后就是最小割了(捂脸 4036

2020.1.20每日一题“归并排序”

佐手、 提交于 2020-01-21 04:42:45
归并排序是什么 归并排序顾名思义有一个化归合并的过程,那要合并在这之前就有分离,这就是归并排序的步骤:先将要排序的一串数字劈开,劈到最小有序数列(也就是一个一个的时候,只有一个那肯定有序啊);第二步再将他们逐渐合并,继而变成一个有序数列。 为什么要用归并排序 算法复杂度: 最好情况:O(nlogn) 最坏情况:O(nlogn) 平均情况:O(nlogn) 空间复杂度:O(n) 稳定性:稳定 从以上的数据 可以看出归并排序比普通的排序在复杂度上有了很好的提升。 归并排序的代码实现: 上面这个代码还可用于求逆序数对的个数。 关键就是这段代码: 来源: CSDN 作者: LeBronGod 链接: https://blog.csdn.net/LebronGod/article/details/104055745

JS 数组常见操作汇总,数组去重、降维、排序、多数组合并实现思路整理

烈酒焚心 提交于 2020-01-18 00:26:15
壹 ❀ 引 JavaScript开发中数组加工极为常见,其次在面试中被问及的概率也特别高,一直想整理一篇关于数组常见操作的文章,本文也算了却心愿了。 说在前面,文中的实现并非最佳,实现虽然有很多种,但我觉得大家至少应该掌握一种,这样在面试能解决大部分数组问题。在了解实现思路后,日常开发中结合实际场景优化实现,提升性能也是后期该考虑的。 本文主要围绕数组去重、数组排序、数组降维、数组合并、数组过滤、数组求差集,并集,交集,数组是否包含某项等知识点展开,附带部分知识拓展,在看实现代码前也建议大家先自行思考,那么本文开始。 贰 ❀ 常见数组操作 贰 ❀ 壹 数组去重 数组去重我分为两种情况,简单数组去重与对象数组去重。所谓简单数组即元素均为基本数据类型,如下: let arr = [undefined, 0, 1, 2, 2, 3, 4, 0, undefined]; let arr_ = arr.filter((self, index, arr) => index === arr.indexOf(self)); console.log(arr_); //[undefined, 0, 1, 2, 3, 4] 有没有更简单的做法?有的同学肯定想到了ES6新增的Set数据结构,这也是去重的妙招,原理是Set结构不接受重复值,如下: [...new Set([undefined, 0, 1,

Lc23-合并K个排序链表

你说的曾经没有我的故事 提交于 2020-01-16 09:32:54
import java.util.ArrayList; import java.util.List; /** * 合并 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 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 * */ public class Lc23 { // 暴力求解 全部拆下来希尔排序,然后重新组装 public static ListNode mergeKLists(ListNode[] lists) { ListNode head = null; if (lists.length == 0 ) { return head; } List<Integer> list = new ArrayList<>(); for (int i = 0; i < lists.length; i++) { ListNode node = lists[i]; while (node != null) { list.add(node.val); node = node.next; }

合并K个排序链表

你说的曾经没有我的故事 提交于 2020-01-12 21:54:34
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 思路: 1: 有k个排序的链表,我们可以先将两个链表进行合并。 2. 合并出来的链表在和一个链表合并,以此类推。 /** * 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) { int size = lists.size(); if (size==0) return nullptr; if (size==1) return lists[0]; ListNode* p= lists[0]; for (int i=1; i<size; i++) { p=mergelist(p,lists[i]); } return p; } ListNode* mergelist(ListNode* list1, ListNode* list2) {

23. 合并K个排序链表

杀马特。学长 韩版系。学妹 提交于 2020-01-11 14:27:03
23. 合并K个排序链表 https://leetcode-cn.com/problems/merge-k-sorted-lists/ 难度 完成日期 耗时 提交次数 困难 2020-1-11 1小时 5 问题描述 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 解题思路 普通方法 ListNode *mergeKLists(vector<ListNode *> &lists) { int length = lists.size(); if (length == 2) { return mergeTwoLists(lists[0], lists[1]); } else { int newLength = length / 2; if (length % 2 == 1) { newLength++; } vector<ListNode *> newLists(newLength); for (int i = 0; i < newLength - 1; i++) { newLists[i] = mergeTwoLists(lists[2 * i], lists[2 * i + 1]); } if (length % 2 == 1) {

算法 简单 | 6. 合并排序数组 II

怎甘沉沦 提交于 2020-01-11 14:22:18
算法 简单 | 6. 合并排序数组 II 题目描述 样例1 样例2 java题解 python题解 题目描述 合并两个有序升序的整数数组A和B变成一个新的数组。 新数组也要有序。 样例1 输入: A = [ 1 ] , B = [ 1 ] 输出: [ 1,1 ] 样例解释: 返回合并后的数组。 样例2 输入: A = [ 1,2,3,4 ] , B = [ 2,4,5,6 ] 输出: [ 1,2,2,3,4,4,5,6 ] 样例解释: 返回合并后的数组。 java题解 使用两个指针分别对数组从小到大遍历,每次取二者中较小的放在新数组中。 直到某个指针先到结尾,另一个数组中剩余的数字直接放在新数组后面。 时间复杂度O(n) class Solution { /** * @param A and B: sorted integer array A and B. * @return: A new sorted integer array */ public int [ ] mergeSortedArray ( int [ ] A , int [ ] B ) { if ( A == null || B == null ) { return null ; } int [ ] result = new int [ A . length + B . length ] ; int i = 0 ,

23. 合并K个排序链表

左心房为你撑大大i 提交于 2019-12-30 02:58:08
23. 合并K个排序链表 题目描述 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6 实现1 每次取出两个链表,合并成一个 /** * 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 ; } ListNode res = lists [ 0 ] ; for ( int i = 1 ; i < lists . length ; i ++ ) { res = insert ( res , lists [ i ] ) ; } return res ; } public ListNode insert ( ListNode list , ListNode list2 ) { if ( list

排序算法之归并排序

你离开我真会死。 提交于 2019-12-28 23:36:43
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> #include <iostream> using namespace std; //归并算法 /** 一句箴言:将待排序数据一分为二,二分为四,四分为八,递归下去,直至每份为1个元素,这一个元素自身一定为有序的,然后再将分了的两两合并为有序数组,最终变成一个有序数组。 方法:递归拆分并两两合并为有序数组。其中合并时候需要将待合并的两组数据拷贝出来,指定左待归并数据索引i,右待归并数据索引j, k为原数组需重新指定值得索引 **/ void _merge(int arr[], int l, int mid, int r) { //归并前判断是否分割的两数组已经左边小右边大了 if (arr[mid+1] > arr[mid]) { return; } //首先需要拷贝出待归并区间的数据 区间为索引l到 r int aux[r - l + 1]; for (int i = l ; i <= r; i++) { aux[i - l] = arr[i]; } /** // 注释的是去除掉偏移量l后的数组 求解法 int max = r -l; int newMid = (max - min) / 2; int i = 0,j = newMid + 1; //遍历原数组l到 r 这个区间