剑指Offer - 九度1348 - 数组中的逆序对
剑指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 - 数组中的逆序对的更多相关文章
- 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字
剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...
- 剑指Offer - 九度1351 - 数组中只出现一次的数字
剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...
- 剑指offer(35)数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 《剑指offer》51:数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 【剑指Offer】35、数组中的逆序对
题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P ...
- 【剑指offer】题目36 数组中的逆序对
数组中任取两个数字,如果前面的数字大于后面的数字称为一个逆序对 如:1,2,1,2,1 有3个逆序对 思路:知道O(N2)肯定是错的.开始想hash,试图找到O(n)的算法,想了很久,找不到.后来想到 ...
- 剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)
剑指Offer - 九度1373 - 整数中1出现的次数(从1到n整数中1出现的次数)2014-02-05 23:03 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直 ...
- 剑指Offer - 九度1517 - 链表中倒数第k个结点
剑指Offer - 九度1517 - 链表中倒数第k个结点2013-11-30 02:57 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含 ...
- 剑指Offer - 九度1384 - 二维数组中的查找
剑指Offer - 九度1384 - 二维数组中的查找2013-11-23 23:23 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...
随机推荐
- OpenGL学习 Our First OpenGL Program
This shows you how to create the main window with the book’s application framework and how to render ...
- windows如何关闭指定端口
关闭windows中被占用的端口,比如我们常见的8080端口被占用了 1.查找端口的PID netstat -aon|findstr "8080" 如图 PID为3888 2.关闭 ...
- 8086汇编语言入门-HelloWorld
附件下载: http://pan.baidu.com/s/1i5R9qO9 密码:rfgk 80x86微处理器汇编语言编程.学习任何编程语言都免不了要跨越HelloWorld这道坎,面向机器的 ...
- Ghostbusters(并查集,最小生成树)
Ghostbusters 时间限制: 1 Sec 内存限制: 128 MB提交: 33 解决: 7[提交] [状态] [讨论版] [命题人:admin] 题目描述 The Bureau of Ap ...
- 20145238-荆玉茗 《Java程序设计》第9周学习总结
20145238第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 ...
- 移动端定制软键盘样式 配置input属性的type属性
1.当你的input输入的数据为链接地址时type属性可改为 type=url 最下面一栏就会出现.com 提高用户体验 2.当你的input输入的数据为email时type属性可改为 type=em ...
- mysql常用命令添加外键主键约束存储过程索引
数据库连接 mysql -u root -p123456 查看表 show databases 创建数据库设置编码 create table books character set utf8; 创建用 ...
- 【JS-Java-EL】JavaScript和Java(EL表达式)引发的 Uncaught SyntaxError: Unexpected token ILLEGAL
2018.10.14 BUG原因: 在较早期的代码中,容易出现 JS 拼接 HTML 代码字符串的情况.如 // 页面 test.jsp 内部的 JS 代码 // ${} JSP中EL语法,内部为Ja ...
- Spring的jdbcTemplate 与原始jdbc 整合c3p0的DBUtils 及Hibernate 对比 Spring配置文件生成约束的菜单方法
以User为操作对象 package com.swift.jdbc; public class User { private Long user_id; private String user_cod ...
- Mantle--国外程序员最常用的iOS模型&字典转换框架
Mantle简介 Mantle是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary)和 ...