常用算法(后面有inplace版本):

 package ArrayMergeSort;

 import java.util.Arrays;

 public class Solution {
public int[] mergeSort(int[] arr) {
if (arr.length == 1) return arr;
else {
int[] arr1 = Arrays.copyOfRange(arr, 0, arr.length/2);
int[] arr2 = Arrays.copyOfRange(arr, arr.length/2, arr.length);
return merge(mergeSort(arr1), mergeSort(arr2));
}
} public int[] merge(int[] arr1, int[] arr2) {
int len1 = arr1.length;
int len2 = arr2.length;
int[] res = new int[len1+len2];
int i = 0, j=0, cur=0;
while (i<len1 && j<len2) {
if (arr1[i] <= arr2[j]) {
res[cur++] = arr1[i++];
}
else {
res[cur++] = arr2[j++];
}
}
while (i<len1) {
res[cur++] = arr1[i++];
}
while (j<len2) {
res[cur++] = arr2[j++];
}
return res;
} /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Solution sol = new Solution();
int[] arr = sol.mergeSort(new int[]{6,5,4,8,2,1});
System.out.println(Arrays.toString(arr));
} }

在如上算法中只需稍作修改,加上一行代码,就可以求数组的逆序对

如数组 <2,3,8,6,1> 的逆序对为:<2,1> <3,1> <8,6> <8,1> <6,1> 共5个逆序对。

暴力法是O(N^2)

mergeSort可以O(NlogN)

定义一个static variable count, 然后在12行加入

 public int[] merge(int[] arr1, int[] arr2) {
int len1 = arr1.length;
int len2 = arr2.length;
int[] res = new int[len1+len2];
int i = 0, j=0, cur=0;
while (i<len1 && j<len2) {
if (arr1[i] <= arr2[j]) {
res[cur++] = arr1[i++];
}
else { // arr1[i] > arr2[j];
res[cur++] = arr2[j++];
count += arr1.length - i;
}
}
while (i<len1) {
res[cur++] = arr1[i++];
}
while (j<len2) {
res[cur++] = arr2[j++];
}
return res;
}

Inplace的mergeSort不是那么好写,我还是在merge的时候用了额外空间

 package ArrayMergeSort;

 import java.util.Arrays;

 public class Solution2 {

     public int[] mergeSort(int[] arr) {
if (arr==null || arr.length==0) return arr;
mergeSort(arr, 0, arr.length-1);
return arr;
} public void mergeSort(int[] arr, int l, int r) {
if (r-l == 0) return;
int m = (l+r)/2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, m+1, r);
} public void merge(int[] arr, int l1, int r1, int l2, int r2) {
int[] temp = new int[r2-l1+1];
int i1=l1, i2=l2, cur=0;
while (i1<=r1 && i2<=r2) {
if (arr[i1] <= arr[i2]) temp[cur]=arr[i1++];
else temp[cur] = arr[i2++];
cur++;
}
while(i1<=r1) temp[cur++]=arr[i1++];
while(i2<=r2) temp[cur++]=arr[i2++];
cur = 0;
for (int i=l1; i<=r2; i++) arr[i]=temp[cur++];
} /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Solution2 sol = new Solution2();
int[] arr = sol.mergeSort(new int[]{6,5,4,2,1});
System.out.println(Arrays.toString(arr));
} }

Iterative Merge Sort大致的算法是,假设每一层需要merge许多数组 A和B数组是其中两个,i 可以理解为A或B的size,从1一直到array.length/2. j 可以理解为一组A和B之中B的结束位置。 Merge函数跟上面一样

 Iterative Merge Sort
public static T[] Iterative(T[] array, IComparer<T> comparer)
{
for (int i = 1; i <= array.Length / 2 + 1; i *= 2)
{
for (int j = i; j < array.Length; j += 2 * i)
{
Merge(array, j - i, j, Math.Min(j + i, array.Length), comparer);
}
} return array;
}

Summary: Merge Sort of Array && 求逆序对的更多相关文章

  1. 【剑指offer】求逆序对的个数

    2013-09-07 10:50:31 面试题36:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字构成一个逆序对.输入一个数组,求出这个数组中逆序对的总数. 小结: 最直观的的方法是: ...

  2. POJ 3067 - Japan - [归并排序/树状数组(BIT)求逆序对]

    Time Limit: 1000MS Memory Limit: 65536K Description Japan plans to welcome the ACM ICPC World Finals ...

  3. POJ 4020 NEERC John's inversion 贪心+归并求逆序对

    题意:给你n张卡,每张卡上有蓝色和红色的两种数字,求一种排列使得对应颜色数字之间形成的逆序对总数最小 题解:贪心,先按蓝色排序,数字相同再按红色排,那么蓝色数字的逆序总数为0,考虑交换红色的数字消除逆 ...

  4. 归并排序+归并排序求逆序对(例题P1908)

    归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然 ...

  5. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

  6. HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少 ...

  7. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  8. 树状数组求逆序对:POJ 2299、3067

    前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换 ...

  9. 浙江工商大学15年校赛I题 Inversion 【归并排序求逆序对】

    Inversion Time Limit 1s Memory Limit 131072KB Judge Program Standard Ratio(Solve/Submit) 15.00%(3/20 ...

随机推荐

  1. 为什么数值类型byte取值范围是(-128~127)?

    在解决这个问题之前,我们先了解几个概念? 一.原码, 反码, 补码的概念 正数的反码和补码都与原码一样: 负数的反码.补码与原码不同,负数的反码:原码中除去符号位,其他的数值位取反,0变1,1变0.负 ...

  2. 微信公众账号开发教程(三) 实例入门:机器人(附源码) ——转自http://www.cnblogs.com/yank/p/3409308.html

    一.功能介绍 通过微信公众平台实现在线客服机器人功能.主要的功能包括:简单对话.查询天气等服务. 这里只是提供比较简单的功能,重在通过此实例来说明公众平台的具体研发过程.只是一个简单DEMO,如果需要 ...

  3. SSH框架中spring的原理

    在ssh项目中,是有明确分工的,spring的作用就相当于将struts和hibernate连接起来,是将两个没有关系的框架的特性,方法,action都放在spring的配置文件中使他们建立关系.取他 ...

  4. Bundle文件的创建和使用(一)

    经常会出现某个需求:将自己的模块或者开放类,封装成静态库给其他人提供方便的调用. 但是当你的模块中需要大量使用xib,图片,音频或者其他资源文件时,无法添加至静态库.这个时候就需要将一些资源文件封装至 ...

  5. express 查看版本号

    新安装了express,但是当查看版本号输入: express -v 时出现如下错误: 网上查找了相关资料才发现express查看版本 的命令是 express -V (即V大写) 再次尝试: 发现同 ...

  6. 20145211 《Java程序设计》第7周学习总结——沧海横流

    教材学习内容总结 Lambda Arrays的sort()方法可以用来排序,在使用sort()时,需要操作java.util.Comparator来进行说明,这样一来,语法就显得有些冗长.在JDK8中 ...

  7. LightOj 1024 - Eid (求n个数的最小公约数+高精度)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1024 题意:给你n(2<=n<=1000)个数, 然后求n个数的最小公倍数 ...

  8. Mac版 MicrosoftOffice2015 办公软件 破解教程

    来自:http://bbs.feng.com/read-htm-tid-9704285.html 下载链接:http://pan.baidu.com/s/1dD6lBFz  提取密码:xu5n 补丁: ...

  9. An unknown Subversion error occurred. (code = 155037)

    这是因为在svn更新时意外中断引起的. 我的解决办法:如果本地没有更改,只是单纯获取svn的项目,则另起一个文件夹,重新checkout: 如果是本地有更改,则复制到新的文件夹,重新update.

  10. 解决在.ashx文件中判断Session 总是NULL的方法

    实现IHttpHandler接口的同时必须继承IRequiresSessionState接口,才能拿到session public class HttpHandler: IHttpHandler, I ...