#返回上一级

@Author: 张海拔

@Update: 2014-01-14

@Link: http://www.cnblogs.com/zhanghaiba/p/3520089.html

 /*
*Author: ZhangHaiba
*Date: 2014-1-15
*File: inverse_number.c
*
*this demo shows two method solving inverse number problem
*/ #include <stdio.h>
#define N 512
#define INF 0x7fffffff; //value of sentinel
int array[N];
int left_tmp[N/+];
int right_tmp[N/+]; //public
int inverse_number_cnt(int *, int);
int inverse_number_cnt2(int *, int);
void merge_sort(int *, int, int, int *);
void set_array(int *, int);
void show_array(int *, int); int main(void)
{
int n; scanf("%d", &n);
set_array(array, n);
int ans;
ans = inverse_number_cnt(array, n);
printf("%d\n", ans);
ans = inverse_number_cnt2(array, n);
printf("%d\n", ans);
return ;
} int inverse_number_cnt(int *a, int n)
{
int i, j, cnt = ; for (i = ; i < n-; ++i)
for (j = i+; j < n; ++j)
if (a[i] > a[j])
++cnt;
return cnt;
} //modify merge_sort:
//add variable cnt
//add code "*cnt = left_len - i;"
void merge_sort(int *a, int l, int r, int *cnt)
{
if (l >= r) return;
else {
int m = l + (r-l)/;
merge_sort(a, l, m, cnt);
merge_sort(a, m+, r, cnt);
int left_len = m-l+, right_len = r-m, i, j = l;
for (i = ; i < left_len; ++i, ++j)
left_tmp[i] = a[j];
left_tmp[i] = INF;
for (i = ; i < right_len; ++i, ++j)
right_tmp[i] = a[j];
right_tmp[i] = INF;
for (i = j = ; l <= r; ++l) {
if (left_tmp[i] <= right_tmp[j])
a[l] = left_tmp[i++];
else {
a[l] = right_tmp[j++];
*cnt += left_len - i;
}
}
}
} int inverse_number_cnt2(int *a, int n)
{
int l = , r = n-, cnt = ; merge_sort(a, l, r, &cnt);
return cnt;
} void set_array(int *a, int n)
{
int i; for (i = ; i < n; ++i)
scanf("%d", a+i);
} void show_array(int *a, int n)
{
int i; for (i = ; i < n; ++i)
printf(i == n- ? "%d\n" : "%d ", a[i]);
}

逆序对的定义:序列A中,当位置i < j,而对应值a[i] > a[j],则称(i, j)构成序列A的一个逆序对。

解法一中,按照定义,通过两个for循环即可求出逆序对数。

即以第i个的元素为起点,j从i+1开始到n-1结束按定义进行验证,从而统计逆序对的个数,显然i的范围是[0, n-2]。

显然解法一的时间复杂度是O(n^2)。

解法二的所用函数几乎就是调用了一个纯粹的归并排序,目的通过计数器cnt的地址来修改cnt,做完归并排序后返回。

这个解法求逆序对数的原理是:对于某一次的归并(有序表的合并),类似二叉树的后序遍历,归并时当右子数组某个元素k进入根数组时,此时左子数组中,下标为i的元素以及它后面的所有元素都与k构成逆序对(左子数组的下标均<左子数组任何一个元素的下标,而k能进入根数组则说明它的值比左子数组剩下的所有元素都小,因此k的下标与上述元素的下标,均构成逆序对),所以有逆序对数要增加left_len - i,即:*cnt += left_len - i。

#返回上一级

怎样求逆序对数(Inverse Number)?的更多相关文章

  1. hdu 4911 求逆序对数+树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=4911 给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 实际上每交换一次能且只能 ...

  2. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  3. 求逆序对数总结 & 归并排序

    用归并排序方式 最原始的方法的复杂度是O(n^2). 使用归并排序的方式,可以把复杂度降低到O(nlgn). 设A[1..n]是一个包含N个非负整数的数组.如果在i〈 j的情况下,有A〉A[j],则( ...

  4. poj 2299 树状数组求逆序对数+离散化

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 54883   Accepted: 20184 ...

  5. codeforces 459D D. Pashmak and Parmida's problem(离散化+线段树或树状数组求逆序对)

    题目链接: D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megab ...

  6. codeforces 540E 离散化技巧+线段树/树状数组求逆序对

    传送门:https://codeforces.com/contest/540/problem/E 题意: 有一段无限长的序列,有n次交换,每次将u位置的元素和v位置的元素交换,问n次交换后这个序列的逆 ...

  7. 牛客练习赛33 D tokitsukaze and Inverse Number (树状数组求逆序对,结论)

    链接:https://ac.nowcoder.com/acm/contest/308/D 来源:牛客网 tokitsukaze and Inverse Number 时间限制:C/C++ 1秒,其他语 ...

  8. 归并求逆序数(逆序对数) && 线段树求逆序数

    Brainman Time Limit: 1000 MS Memory Limit: 30000 KB 64-bit integer IO format: %I64d , %I64u   Java c ...

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

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

随机推荐

  1. 【OCP-12c】CUUG 071题库考试原题及答案解析(21)

    3.choose three View the Exhibit and examine the description of SALES and PROMOTIONS tables. You want ...

  2. css如何去掉select原始样式

    css代码: select { /*将默认的select选择框样式清除*/ appearance: none; -moz-appearance: none; -webkit-appearance: n ...

  3. 多个音频audio2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. sonarLint和sonarQube

    在线安装和离线装sonarLint https://blog.csdn.net/limm33/article/details/51166840 下载指定版本的sonarLint https://bin ...

  5. Python(序列化json,pickle,shelve)

    序列化 参考:https://www.cnblogs.com/yuanchenqi/articles/5732581.html # dic = str({'1':'111'}) # # f = ope ...

  6. (转)搞个这样的APP要多久?心酸啊。

    这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正对面坐着来访的王总,他是在别处打拼的人,这几年据说收获颇丰,见移动互联网如火如荼,自然也想着要 ...

  7. (转)C# 正则表达式

    最近写爬虫时需要用到正则表达式,有段时间没有使用正则表达式现在渐渐感觉有些淡忘,现在使用还需要去查询一些资料.为了避免以后这样的情况,在此记录下正则表达式的一些基本使用方法附带小的实例.让以后在使用时 ...

  8. C#集合通论

    前言 写这篇文章的最初动力是来自于一次笔试经历.有一道笔试题大概是这样的:程序使用一个txt文件来存储操作记录.存储记录是多行字符串,每一行代表一次操作记录,格式如下:用户名+操作事项名称+操作时间. ...

  9. javascript中childNodes与children的区别

    1.childNodes:获取节点,不同浏览器表现不同: IE:只获取元素节点: 非IE:获取元素节点与文本节点: 解决方案:if(childNode.nodeName=="#text&qu ...

  10. 【Kafka源码】Kafka启动过程

    一般来说,我们是通过命令来启动kafka,但是命令的本质还是调用代码中的main方法,所以,我们重点看下启动类Kafka.源码下下来之后,我们也可以通过直接运行Kafka.scala中的main方法( ...