【归并排序】-求逆序数算法
1.归并排序
- 归并排序是分治法的一种典型应用,应用递归思想,自顶向下思考:先假定
MergeSort()
可以将一个乱序数组排好序,因此可以开始分
(将一个数组平均分成两部分),再治
(分别调用MergeSort()
使前后两部分有序),最后使用Merge()
将两个有序数组合并为一个有序数组。 Merge()
方法实现简单,只需管理两个指针,分别指向待合并的两个数组,开辟辅助数组保存中间结果,O(n)
时间复杂度即可完成
2.逆序数
- 逆序数的定义:如果
i < j
且A[i] > A[j]
.则A[i]
和A[j]
即为逆序数对.逆序数对的个数就叫逆序数 - 求逆序数可以通过管理两个指针,两次扫描数组,蛮力法求出,显然时间复杂度是
Θ(n^2)
. - 利用归并排序法,稍做改进即可.在
Merge()
中,合并两个已经有序的数组A,B.因为A.B有序,所以,A,B各自的逆序数是0,所以AB的逆序数等于A,B之间的逆序数. - 举个例子:
A=1,4,6,7,9
,B=2,3,5,10,13,21
.在Merge中发现当前i号元素4比2大,那么4的逆序数需要+1,又因6,7,9都排在4后面,那么6,7,9的逆序数也应该+1,所以总体的逆序数应该加上last-i+1
.
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {public int InversePairs(int[] array) {int len = array.length;int[] c = new int[len];count = 0;MergeSort(array, 0, len - 1, c);return count;}public static int MOD = 1000000007;public static int count = 0;//新增public static void Merge(int[] array, int left, int mid, int right, int[] c) {int i = left;int j = mid + 1;int k = left;while (i <= mid && j <= right) {if (array[i] <= array[j])c[k++] = array[i++];else {c[k++] = array[j++];//count += mid - i + 1;//新增count = (count + mid - i + 1) % MOD;}}while (i <= mid)c[k++] = array[i++];while (j <= right)c[k++] = array[j++];//C数组已经有序,将数组复制回原数组for (int in = left; in <= right; in++) {array[in] = c[in];}}public static void MergeSort(int[] array, int left, int right, int[] c) {if (left < right) {int mid = (left + right) / 2;MergeSort(array, left, mid, c); //将第一个数组排好MergeSort(array, mid + 1, right, c); //将第二个数组排好Merge(array, left, mid, right, c); //合并两个有序数组}}
}
【归并排序】-求逆序数算法相关推荐
- 【归并排序】求逆序数算法
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序. 一个排列中逆序的总数就称为这个排列的逆序数.逆序数为偶数的排列称为偶排列:逆序数为奇数的排列称为奇排 ...
- 洛谷P2717 寒假作业(cdq分治+归并排序求逆序数)
2020.6.13 君子做事得有担当,这个题目我确实不太明白什么意思,只会O(N^2)的朴素解法,看了下题解才发现有逆序数的弟弟顺序数,用归并就过了?? 先去打cf div2,等会再来研究 代码: # ...
- 归并排序求逆序对(C语言)
目录 1.归并排序过程 (1)逆序对概念 (2)基本思想 (3)算法实现 1.归并排序过程 使用归并排序实现求逆序对,那么首先得了解什么是归并排序(关于归并排序可以求逆序对,也是在做题中学会的). 首 ...
- hust1347(归并排序求逆序对)
题意: 给出一个数列,你要对这个数列的数字进行k次交换操作,使得交换之后的数列逆序对虽少. 思路: 求原数列的逆序对,再和k比就行了.求逆序对要用归并排序,因为树状数组开不下. 代码: #includ ...
- 分治法:归并排序求逆序对
现给出这个定义,什么是逆序对,NOIP火柴排队这个题是逆序对的一个比较好的例题,这里我们只讨论求逆序对的一些高效的算法 一般有归并排序以及树状数组两种方法,本文只讨论归并排序求逆序对 这里不给出原理只 ...
- 高级排序求逆序数之分治法
前面几篇文章都有讲分治法,分而治之,一种很典型的算法思想,现在求逆序数,如果是你初次接触,一般都会想到冒泡法来统计逆序数.不过冒泡法的时间复杂度确实高(n²),所以接下来运用分治法来实现,复杂度为(n ...
- C语言实现逆序数线性代数,线性代数之求逆序数
线性代数之求逆序数 在线性代数中,经常要求序列的逆序数,即所有逆序之和.在一个排列中若较大的数字排在较小数字的左边,则成这两个数字构成一个逆序.求解过程用C语言描述如下: #define N 5 in ...
- hdu 1394(树状数组求逆序数)
解题思路:这道题是求循环数组中逆序数最小值,求逆序数这里肯定是用树状数组.只是这里有一点点变化,由于题目中n位数是0-n-1的一个排列,所以num[i]可表示为比num[i]小的数的个数.把第一位的数 ...
- nyoj117求逆序数 并归排序法
题目链接:http://115.159.40.116/problem_show.php?pid=4729 或者:http://acm.nyist.net/JudgeOnline/problem.php ...
最新文章
- Pytorch install
- 【小技巧】notepad++ 输入中文无响应
- ROW_NUMBER、RANK()、DENSE_RANK()和OVER的使用
- LinkButton指定ClientOnClick的问题
- china-pub近7日计算机图书排行榜
- 【Elasticsearch】 es Bootstrap Checks Failed
- mybatis自动生成mapping和实体
- 如何使Android应用程序获取系统权限来修改系统时间
- Linux编译和下载嵌入式实验,嵌入式实验6交叉编译及Linux简单程序设计实验
- 传智168期 day61 redis 笔记(2017年8月25日19:16:30)
- 外观模式又叫门面模式?
- 第十四届恩智浦智能汽车大赛车队规划概要
- Barra风险模型简介
- 学习日记day29 平面设计 色彩
- html的div背景,html div背景到底是什么颜色呢?
- IMAP4 读取收件箱的问题
- html上绘制网格线,【玩转D3.js】--(1)绘制网格线
- CURA汉化 语言修改 本地化 locale
- 微信抢票环境配置——nginx + uwsgi + django配置服务器
- SOCKET 实现NAT 穿越
热门文章
- RE:SB的SDOISB记
- ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQLEF
- c# namespace不能和class的name 相同
- SysErrorMessage 函数和系统错误信息表
- dods 机器人_胜利之日机器人补丁
- php 定时脚本执行wget无效_写了个Bug,误执行rm fr /*,瞬间背后一凉!
- linux 搭建.net运行环境,.net core运行环境搭建 linux + windows
- flink physical partition
- java项目导入包报错_转!java web项目 build path 导入jar包,tomcat启动报错 找不到该类...
- mysql创建库和表确保utf8_mysql创建utf8数据库