求数组逆序对个数
2016-04-09 20:39
169 查看
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数class Solution {
public:
int InversePairs(vector<int> data) {
return mergesort(data,0,(int)data.size());
}
int merge(vector<int> &data, int s,int mid,int e){
auto it = data.begin();
vector<int> a1(it+s, it+mid); a1.push_back(INT_MAX);
vector<int> a2(it+mid, it+e); a2.push_back(INT_MAX); // 归并排序中加入哨兵
int i1=0,i2=0,i=s;
int count=0;
while(i<e){
if(a1[i1]<=a2[i2]){ // 注意这里必须是<=,因为2数相等不算逆序
data[i] = a1[i1];
i1++;
}else{
data[i] = a2[i2];
i2++;
count += mid-s-i1; // 逆序个数为还没进入data的i1的个数
} i++; } return count; } int mergesort(vector<int> &data, int s, int e){ if (s+1>=e) return 0; int mid = (e-s)/2+s; int c1 = mergesort(data, s, mid); int c2 = mergesort(data, mid, e); return merge(data,s,mid,e)+c1+c2; } };
对于数组 [6, 5, 4, 3, 2, 1],逆序对为15个。
总的思路就是归并排序的思路,求一个数组的逆序,包括3部分,一是数组前半部分的逆序,二是数组后半部分的逆序,三是一个在前,一个在后形成的逆序。
我们发现,一和二是原问题的子问题,因此可以用递归描述;
三是一个新的问题:即数组a和数组b中各出一个元素,问能形成多少对逆序。在a和b无序的情况下,需要进行n*n次比较(假设a和b的元素个数都为n),
但a和b有序的情况下,只需要进行2n次比较,并且在比较完成后将a和b归并为一个有序序列。因此对于该问题,在求解完成后得到的数组一定是有序的。
相关文章推荐
- JAVA String 类 总结(1)
- java集合中各个接口与实现类的区别
- Hbase 学习笔记3----操作以及维护
- FZU 2029 买票问题 树状数组+STL
- [Bug-IOS] - linker command failed with exit code 1 (use -v to see invocation)
- 图形界面系统XFree86的历史
- 目标特征检测之FAST特征
- QML 中的 console 对象
- Codeforces 630G Challenge Pennants【组合数学】
- 哈夫曼树
- 如何巧妙的使用sshpass来提高效率
- 第6周
- 关于enum的那些事儿
- UISearchBar会有灰色背景一闪
- uva 574 Sum It Up
- 顺序表的实现
- 基本字符串压缩
- asp微信公众号自动回复开发案列之新闻查询机器人
- Eclipse 快捷键大全
- 触发器限制对表修改