剑指Offer - 九度1348 - 数组中的逆序对
2014-01-30 23:19
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
输入:
每个测试案例包括两行:
第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
第二行包含n个整数,每个数组均为int类型。
输出:
对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。
样例输入:
4
7 5 6 4
样例输出:
5
题意分析:
  这一题的任务是求出一个数组的逆序数,也就是只通过交换相邻元素的方式,将这个数组排成升序的最少交换次数。定义可参见百度百科:逆序数。
  按照冒泡或者选择排序的方法,能很直观地求出逆序数,因为执行的操作就是交换相邻元素。但问题也很明显,效率太低无法满足时间要求。
  快速排序、堆排序、归并排序应该都能对应地找出算逆序数的方法,而且时间上有优势。三者中归并排序的写法和分析方法明显比另外两者要简单,于是我选择了归并排序。
  归并排序的思路很简单:
    1. 排序前一半
    2. 排序后一半
    3. 合并两个已排序的子数组
  对于a[i]~a[j]和a[j+1]~a[k]这么两段儿,如果两段都已经排好了序,且存在左半段的某个a[x]>右半段的某个a[y]的话,那么a[x]、a[x+ 1]、...、a[j]必然都大于a[y]。
  按上面那种算法,一次就多了j-x+1个逆序数。这么一来,就不用一个一个地算了。要是真一个一个地算逆序数,时间复杂度必然是O(n^2)了,因为逆序数本身就是O(n^2)数量级的。
  最后,别忘了用64位整数来存结果,因为10^5个数,逆序数最多可以是5*10^左右,超出了int的范围。
  时间复杂度O(n * log(n)),空间复杂度O(n)。
 // 687950    zhuli19901106    1348    Accepted    点击此处查看所有case的执行结果    1800KB    1093B    100MS
//
#include <cstdio>
using namespace std; const int MAXN = ;
int a[MAXN];
int n;
long long int res;
int tmp[MAXN]; void merge_sort_recursive(int a[], int ll, int rr)
{
if (ll >= rr) {
return;
}
int mm;
mm = (ll + rr) / ;
merge_sort_recursive(a, ll, mm);
merge_sort_recursive(a, mm + , rr); int i, j, k; i = ll;
j = mm + ;
k = ll;
while (true) {
if (i <= mm) {
if (j <= rr) {
if (a[i] <= a[j]) {
tmp[k++] = a[i++];
} else {
tmp[k++] = a[j++];
res += mm - i + ;
}
} else {
tmp[k++] = a[i++];
}
} else {
if (j <= rr) {
tmp[k++] = a[j++];
} else {
break;
}
}
}
for (i = ll; i <= rr; ++i) {
a[i] = tmp[i];
}
} int main()
{
int i; while (scanf("%d", &n) == ) {
for (i = ; i < n; ++i) {
scanf("%d", &a[i]);
}
res = ;
merge_sort_recursive(a, , n - );
printf("%lld\n", res);
} return ;
}

剑指Offer - 九度1348 - 数组中的逆序对的更多相关文章

  1. 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字

    剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...

  2. 剑指Offer - 九度1351 - 数组中只出现一次的数字

    剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...

  3. 剑指offer(35)数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  4. 《剑指offer》51:数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  5. 【剑指Offer】35、数组中的逆序对

      题目描述:   在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P ...

  6. 【剑指offer】题目36 数组中的逆序对

    数组中任取两个数字,如果前面的数字大于后面的数字称为一个逆序对 如:1,2,1,2,1 有3个逆序对 思路:知道O(N2)肯定是错的.开始想hash,试图找到O(n)的算法,想了很久,找不到.后来想到 ...

  7. 剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)

    剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)2014-02-05 23:03 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直 ...

  8. 剑指Offer - 九度1517 - 链表中倒数第k个结点

    剑指Offer - 九度1517 - 链表中倒数第k个结点2013-11-30 02:57 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含 ...

  9. 剑指Offer - 九度1384 - 二维数组中的查找

    剑指Offer - 九度1384 - 二维数组中的查找2013-11-23 23:23 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...

随机推荐

  1. vue - 绑定css、style

    1.绑定html css1.1对象语法: 传给 v-bind:class 一个对象,以动态地切换 class <div v-bind:class="{ active: isActive ...

  2. 如何更换vim-airline的theme

    仓库位置: 点我直达 (主题以前是和airline在同个仓库的,现在独立出来了) 这些内置的这些主题,可以直接使用,方法是在 “.vimrc”文件中写 let g:airline_theme=&quo ...

  3. java IO流——字节流

    字节流主要操作byte类型数据,以byte数组为准,主要操作类有InputStream(字节输入流).OutputSteam(字节输出流)由于IputStream和OutputStream都是抽象类, ...

  4. 解决Zend加密的PHP页面出现Incompatible file format的问题

    错误如图: 致命错误:不兼容的文件格式可能的原因: 1.文件本身加密的问题,很有可能你用的Zend进行加密了,但是因为版本的问题,很有可能是你的主机上的Zend Optimizer版本太低了.2.文件 ...

  5. redis 有序集合类型

  6. Java-笔记1

    /* 对第一个java程序进行总结 1. java程序编写-编译-运行的过程 编写:我们将编写的java代码保存在以".java"结尾的源文件中 编译:使用javac.exe命令编 ...

  7. Python的socket编程

    我们知道两个进程如果需要进行通讯最基本的一个前提能能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大,这时候我们需要 ...

  8. 关于 ReactNative 环境搭建之 error: invalid developer directory '/Library/Developer/CommandLineTools' - RN

    简要说明,此次尝试安装 ReactNative 时当前 MacPro 版本为 10.13.6.Xcode 版本为 Version 9.4.1 (9F2000),按照官方的完整原生环境搭建流程一步步执行 ...

  9. SQL基础语句汇总

    连接数据库 1 mysql -h10.20.66.32 -uroot -p123456 -h后面是mysqlServer所在地址,-u后面是用户名,-p后面是密码 查看数据库 1 show datab ...

  10. Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合

    思路shiro使用FormAuthenticationFilter进行表单认证,验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验. 需要写FormAu ...