数组中的逆序对
2016-03-12 16:03
274 查看
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求这个数组中逆序对的总队数。
扫描数组的方法并不高效,时间复杂度为O(N*N),我们可以考虑拆分数组,每次平均拆分成两组,一直拆到每组数组均有一个元素,我们设置两个指针分别指向两个字数组的末尾,每次比较指针指向的数字,如果第一个数字大于第二个数字,则构成逆序对,并且逆序对的数字等于第二个数组中的数字个数,如果第一个数字小于等于第二个数组,则不构成逆序对,每一次比较之后我们都把较大的数字从后往前复制到一个辅助数组中,确保辅助数组中是递增的。
扫描数组的方法并不高效,时间复杂度为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; }
相关文章推荐
- linux splice使用示例 (使用socket服务于单用户的回射服务器)
- hive日志分析
- Hive中metastore(元数据存储)三种方式区别和搭建
- Python简单介绍
- 【最小生成树】[USACO 2016 February Contest, Gold]Fenced In
- 利用.dSYM和.app文件准确定位Crash位置
- 调试台自动多出现一个'' ,我 用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个''
- Hdu 5611 Baby Ming and phone number【日期计算等等】
- Java中常用的网站
- java获取图片朝向并旋转
- RAID的使用详解
- list排序
- java.util.Timer类可以实现多线程一样的功能
- Android手动打包
- [leetcode 298] Binary Tree Longest Consecutive Sequence---求二叉树连续序列的长度
- 1014-34-首页15-计算原创微博的frame------计算cell的高度---计算 UILabel 的 CGSize 的方法
- 非对称加密(RSA)示例
- 电脑装两个jdk,怎么进行转换!
- react.js-05-children遍历数组组件
- 大整数类BigInteger