题目原文:

An inversion in an array a[] is a pair of entries a[i] and a[j] such that i<j but a[i]>a[j]. Given an array, design a linearithmic algorithm to count the number of inversions.

分析:

如果没有性能限制,用插入排序算法可以实现。题目性能被限制在nlogn,又是归并排序的练习题,很显然要实现个归并排序,并在里面计数。通过一个例子来看下计数方法,例如{6, 5, 2, 3, 4, 1}这个序列,归并过程中会分为分为如下几步:

1. 归并{6, 5},存在一次右侧元素5移至左侧的操作,变成{5, 6},归并前逆序对<6,5>

2. 归并{5, 6, 2},存在一次右侧元素2移至左侧的操作, 变成{2, 5, 6},归并前存在两对逆序对<5, 2>和<6, 2>

3. 归并{3, 4},不存在右侧元素左移操作

4. 归并{3, 4, 1},存在一次右侧元素1移至左侧的操作,变成{1, 3, 4},归并前存在两对逆序对<3, 1>和<4, 1>

5. 归并{2, 5, 6, 1, 3, 4},存在三次1、3、4右侧元素移至左侧的操作,归并前存在七对逆序对<2,1><5,1><6,1><5,3><6,3><5,4><6,4>

由上述分析可见,当右侧元素a[j]与左侧元素a[i]进行比较后需要移至左侧时,a[j]与区间 [ a[i] , a[mid] ]中的所有元素都可以组成逆序对,这个区间的元素个数为mid+1-i个。

因此代码如下:

 import java.util.Arrays;

 /**
* @author evasean www.cnblogs.com/evasean/
*/
public class CountInversions {
private static Comparable[] aux;
private static int num = 0; // 逆序对计数 private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
} public static int inversionsNum(Comparable[] a) {
aux = new Comparable[a.length];
sort(a, 0, a.length - 1);
return num;
} private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo)
return;
int mid = lo + (hi - lo) / 2;
sort(a, lo, mid);
sort(a, mid + 1, hi);
merge(a, lo, mid, hi);
} private static void merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo;
int j = mid + 1;
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
for (int k = lo; k <= hi; k++) {
if (i > mid) // i>mid表示aux的左半侧已经被全部被放于a中,直接将右半侧部分放入a
a[k] = aux[j++];
else if (j > hi) // j>hi表示aux的右半侧已经被全部被放于a中,直接将左半侧部分放入a
a[k] = aux[i++];
else if (less(aux[j], aux[i])){ // 右侧元素小于左侧元素时,将右侧元素放入
num += mid+1-i; //此时右侧的这个元素a[j]和[a[i],a[mid]]整个区间的元素都是逆序对
a[k] = aux[j++];
}else a[k] = aux[i++];
}
//System.out.println(Arrays.toString(a));
} public static void main(String[] args) {
Integer[] a = { 6,5,2,3,4,1 };
System.out.println(inversionsNum(a));
System.out.println(Arrays.toString(a));
}
}

Coursera Algorithms week3 归并排序 练习测验: Counting inversions的更多相关文章

  1. Coursera Algorithms week3 归并排序 练习测验: Shuffling a linked list

    题目原文: Shuffling a linked list. Given a singly-linked list containing n items, rearrange the items un ...

  2. Coursera Algorithms week3 归并排序 练习测验: Merging with smaller auxiliary array

    题目原文: Suppose that the subarray a[0] to a[n-1] is sorted and the subarray a[n] to a[2*n-1] is sorted ...

  3. Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)

    题目原文 Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respec ...

  4. Coursera Algorithms week3 快速排序 练习测验: Decimal dominants(寻找出现次数大于n/10的元素)

    题目原文: Decimal dominants. Given an array with n keys, design an algorithm to find all values that occ ...

  5. Coursera Algorithms week3 快速排序 练习测验: Nuts and bolts

    题目原文: Nuts and bolts. A disorganized carpenter has a mixed pile of n nuts and n bolts. The goal is t ...

  6. Coursera Algorithms week1 算法分析 练习测验: Egg drop 扔鸡蛋问题

    题目原文: Suppose that you have an n-story building (with floors 1 through n) and plenty of eggs. An egg ...

  7. Coursera Algorithms week1 算法分析 练习测验: 3Sum in quadratic time

    题目要求: Design an algorithm for the 3-SUM problem that takes time proportional to n2 in the worst case ...

  8. Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法

    第二周课程的Elementray Sorts部分练习测验Interview Questions的第3题荷兰国旗问题很有意思.题目的原文描述如下: Dutch national flag. Given ...

  9. Coursera Algorithms week4 基础标签表 练习测验:Inorder traversal with constant extra space

    题目原文: Design an algorithm to perform an inorder traversal of a binary search tree using only a const ...

随机推荐

  1. [Windows Server 2008] Serv-U安全设置

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:Serv- ...

  2. Java_Web三大框架之Hibernate增删改查

    下面介绍一下Hibernate的增删改查. 第一步:编写用户实体类以及User.hbm.xml映射 package com.msl.entity; public class User { privat ...

  3. ABP初始化

    默认认为你手中已经有abp-zero项目,当前4.6.0 angularJS切换到jquery 运行项目,初始化是跳转到~/App/common/views/layout/layout.cshtml, ...

  4. 查看APK包名签名等信息

    有些游戏第三方比如分享需要配置游戏包名和签名,不同渠道包名签名又不同,所以时常需要查看不同apk包等签名信息,之前是使用等微博开放平台的手机客户端查看apk签名,前提是知道包名,网上找了下查看签名和包 ...

  5. 实现动画之CSS与JavaScript对比

    曾经某个时期,大多数开发者使用 jQuery 给浏览器中的元素添加动画.让这个淡化,让那个扩大,很简单.随着互动的项目越来越复杂,移动设备的大量增加,表现性能变得越来越重要.Flash 被抛弃,有天赋 ...

  6. unzip 命令巧用举例

    1.把文件解压到当前目录下 unzip master.zip 2.如果要把文件解压到指定的目录下,需要用到-d参数. unzip -d /tmp master.zip 3.解压的时候,有时候不想覆盖已 ...

  7. 用jquery-easyui的布局layout写后台管理页面

    先在官网下载easyui文档 引入头部文件 <link rel="stylesheet" type="text/css" href="${pag ...

  8. 爬虫之cookie

    什么是cookie: 在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第一次登 ...

  9. HUD 1426 Sudoku Killer (DFS)

    链接 : Here! 思路 : 记录下所有 "?" , 出现的位置, 然后 $DFS$ 一下, 对于每个位置来说都可以填充 $9$ 种数值, 然后对于判断填充是否合法需要三个标记数 ...

  10. (蓝桥杯)第八届A组C/C++方格分割

    #include<iostream> #include<memory.h> #include<stack> #include<string> #incl ...