/*
版权归《剑指offer——名企面试官精讲典型编程题》所有
题目出处:第五章 优化时间和空间效率 P189
*/
/*
数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数
例如在数组{7,5,6,4}中,一共存在5对逆序对,分别是{7,6},{7,5},{7,4},{6,4},{5,4}
*/
/*
最简单的办法是顺序扫描整个数组,时间复杂度O(n^2),空间复杂度O(1)
另一种方法是归并排序的方法,时间复杂度O(nlogn),空间复杂度O(n)
分解数组,直到单位长度,如果后面的数字小于前面的数字,则显然是逆序对,然后再合并两个单位长度的数组
*/
#include<stdio.h>
#include<malloc.h>
int InversePairsCore(int *data, int *copy, int start, int end)
{
if(start == end)
{
copy[start] = data[start];
return 0;
}
int length = (end - start)/2;
//分别计算数组的左右两边
int left=InversePairsCore(data, copy, start, start+length);
int right=InversePairsCore(data, copy, start+length+1, end);
//第一段数组的最后那个数字的位置
int i=start+length;
//第二段数组的最后那个数字的位置
int j=end;
int count = 0;
int copy_index = end;
while(i>=start && j>(start+length))
{
if(data[i]>data[j])
{
copy[copy_index--] = data[i--];
count += j - start - length;
}
else
{
copy[copy_index--] = data[j--];
}
}
//把剩下也填进去
for(; i>=start; --i)
copy[copy_index--] = data[i];
for(; j>start+length; --j)
copy[copy_index--] = data[j];
//原书中并没有这段代码,可能是编书时漏掉了
for(i=start; i<=end; ++i)
data[i] = copy[i];
return left + right + count;
}
int InversePairs(int *data, int length)
{
if(data==NULL || length<0)
{
return 0;
}
int *copy = (int*)malloc(sizeof(int)*length);
int i;
for(i=0;i<length;++i)
copy[i]=data[i];
int count = InversePairsCore( data, copy, 0, length-1);
free(copy);
return count;
}
int main()
{
//int arr[4]={7,5,6,4};
//int arr[1]={1};
//int *arr = NULL;
int arr[3] = {3,1,2};
printf("count = %d \n",InversePairs(arr,3));
return 0;
}
数组中的逆序对计算
最新推荐文章于 2024-04-23 11:09:00 发布