标签:
题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
思路:
采用归并排序的思想,将数组中的元素分割成子数组,先统计出子数组里的逆序对的个数。同时将这些子数组的数字排成有序的
慢慢往多的合并,在合并的过程中一面统计逆序对的个数,一面合并成一个数组时将里面排好序。
和合并排序类似,时间复杂度为O(nlogn)
下面是详细代码:
#include<iostream> #include<vector> using namespace std; //这里将将vec分成很多段,每一段长度为2s,将2s中前面的s和后面的s是已经排好序的 //现在将它们合并,并记录其中的逆序对,并将合成后的结果放到vec1中。 int jishu1(vector<int>& vec,vector<int>& vec1,int s,int n) { if(s>=n) return 0; int re=0; int i=0; int k1=i; int k2=i+s; int k3=i; //只要前面的一段s还是没有超出范围即可接着循环 while(i+s-1<n) { k1=i; k2=i+s; k3=i; while(k1<=i+s-1&&k2<=i+2*s-1&&k2<n) { if(vec[k1]>vec[k2]) { re+=(s-(k1-i)); vec1[k3]=vec[k2]; k2++; k3++; } else { vec1[k3]=vec[k1]; k1++; k3++; } } while(k1<=i+s-1) { vec1[k3]=vec[k1]; k1++; k3++; } while((k2<=(i+2*s-1))&&k2<n) { vec1[k3]=vec[k2]; k2++; k3++; } i+=2*s; } while(i<n) { vec1[k3]=vec[i]; i++; } return re; } int jishu(vector<int>& vec) { if(vec.empty()) return 0; int n=vec.size(); int re=0; vector<int> vec1(n,0); int s=1; while(1) { re+=jishu1(vec,vec1,s,n); vec=vec1; if(s>=n) break; s*=2; } return re; } int main() { int ary[4]={7,5,6,4}; vector<int> vec(ary,ary+4); cout<<jishu(vec)<<endl; system("pause"); }
标签:
原文地址:http://www.cnblogs.com/yanliang12138/p/4775904.html