正在网易云课堂学习王宏志老师的算法设计与分析入门篇课程视频,将学习中的作业问题发上来与大家一同讨论。这篇是对第三周的作业第一题个人的一些思路,希望与大家一同学习。能通过的完整源代码就不发了。
题目内容:
给定 n 个数组成的数组,求其逆序对的总数。 逆序对定义为,存在 (i, j) 满足 i < j 且 A[i] > A[j] 的二元组的数目。
输入格式:
第一行包含一个整数,表示数组的项数。 接下来的一行,包含 $n$ 个数($$\leq 100000$$),依次表示 Ai(Ai ≤ 109)。
输出格式:
输出一行表示对应的答案。
输入样例:
5
1 3 2 5 4
输出样例:
2
第一次用类似快排的方法原理就是用第一个数将所有数分为比他小和大于等于他两部分,存在两个队列里遇到比他小的,就将逆序对数加上存大数队列的元素个数加一(第一个数本身)。然后将两个队列递归。
代码如下:不过超时了。
int num = 0;
int *p = new int[100000];
int *p1 = new int[100000];
void nixushu(int *p,int *p1,int begin,int end,bool sx){
int data = p[begin];
int da = begin, xiao = end-1;
for (int i = begin + 1; i < end; i++){
if (p[i] < data){
int a = p[i];
p1[xiao--] = p[i];
if (sx)
num = num + da + 1;
}
else{
p[da++] = p[i];
if (!sx)
num = num + end - xiao;
}
}
if (begin + 1 != da)
nixushu(p1, p, begin, da, sx);
if (xiao + 1 != end)
nixushu(p,p1,xiao,end,!sx);
}
超时的原因,个人认为可能是使用队列了,所以将代码改进,用两个数组来代替队列。
代码如下:还是超时。
extern int num = 0;
void nixushu(queue <int> &p){
if (p.empty())
return;
queue <int> p1, p2;
int data = p.front();
p.pop();
int d;
while (!p.empty()){
d = p.front();
p.pop();
if (d < data){
p1.push(d);
num += p2.size() + 1;
}
else{
p2.push(d);
}
}
nixushu(p1);
nixushu(p2);
}