您的位置:首页 > 其它

数组中的逆序对

2016-03-12 16:03 274 查看
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求这个数组中逆序对的总队数。

扫描数组的方法并不高效,时间复杂度为O(N*N),我们可以考虑拆分数组,每次平均拆分成两组,一直拆到每组数组均有一个元素,我们设置两个指针分别指向两个字数组的末尾,每次比较指针指向的数字,如果第一个数字大于第二个数字,则构成逆序对,并且逆序对的数字等于第二个数组中的数字个数,如果第一个数字小于等于第二个数组,则不构成逆序对,每一次比较之后我们都把较大的数字从后往前复制到一个辅助数组中,确保辅助数组中是递增的。

// InversePairs.cpp : Defines the entry point for the console application.
//

// 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛

#include "stdafx.h"

int InversePairsCore(int* data, int* copy, int start, int end);

int InversePairs(int* data, int length)
{
if(data == NULL || length < 0)
return 0;

int* copy = new int[length];
for(int i = 0; i < length; ++ i)
copy[i] = data[i];

int count = InversePairsCore(data, copy, 0, length - 1);
delete[] copy;

return count;
}

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(copy, data, start, start + length);
int right = InversePairsCore(copy, data, start + length + 1, end);

// i初始化为前半段最后一个数字的下标
int i = start + length;
// j初始化为后半段最后一个数字的下标
int j = end;
int indexCopy = end;
int count = 0;
while(i >= start && j >= start + length + 1)
{
if(data[i] > data[j])
{
copy[indexCopy--] = data[i--];
count += j - start - length;
}
else
{
copy[indexCopy--] = data[j--];
}
}

for(; i >= start; --i)
copy[indexCopy--] = data[i];

for(; j >= start + length + 1; --j)
copy[indexCopy--] = data[j];

return left + right + count;
}

// ====================测试代码====================
void Test(char* testName, int* data, int length, int expected)
{
if(testName != NULL)
printf("%s begins: ", testName);

if(InversePairs(data, length) == expected)
printf("Passed.\n");
else
printf("Failed.\n");
}

void Test1()
{
int data[] = {1, 2, 3, 4, 7, 6, 5};
int expected = 3;

Test("Test1", data, sizeof(data) / sizeof(int), expected);
}

// 递减排序数组
void Test2()
{
int data[] = {6, 5, 4, 3, 2, 1};
int expected = 15;

Test("Test2", data, sizeof(data) / sizeof(int), expected);
}

// 递增排序数组
void Test3()
{
int data[] = {1, 2, 3, 4, 5, 6};
int expected = 0;

Test("Test3", data, sizeof(data) / sizeof(int), expected);
}

// 数组中只有一个数字
void Test4()
{
int data[] = {1};
int expected = 0;

Test("Test4", data, sizeof(data) / sizeof(int), expected);
}

// 数组中只有两个数字,递增排序
void Test5()
{
int data[] = {1, 2};
int expected = 0;

Test("Test5", data, sizeof(data) / sizeof(int), expected);
}

// 数组中只有两个数字,递减排序
void Test6()
{
int data[] = {2, 1};
int expected = 1;

Test("Test6", data, sizeof(data) / sizeof(int), expected);
}

// 数组中有相等的数字
void Test7()
{
int data[] = {1, 2, 1, 2, 1};
int expected = 3;

Test("Test7", data, sizeof(data) / sizeof(int), expected);
}

void Test8()
{
int expected = 0;

Test("Test8", NULL, 0, expected);
}

int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: