【剑指offer】面试题36-数组中的逆序对
2017-01-21 14:54
246 查看
题目描述:
在数组中的两个数字如果前边的数字大于后边的数字,则这两个数值组成一个逆序对。输入一个数组,求出这个数组中逆序对的总数。问题分析:
方法1:粗暴的办法。具体实现方法:从数组中的第一个元素开始进行遍历,每次都去该元素之后的元素中查找多少个小于当前元素的值,然后进行统计。返回结果即可。
时间复杂度O(N*N),空间复杂度O(1)。
方法2:归并排序的思想。
由于上述方法的时间复杂度比较高,这里我们不妨采用空间换取时间的方法去统计逆序对的总数。
具体实现办法:
将数组划分成两个子数组,再将子数组分别划分成两个子数组,统计每个子数组内的逆序对个数,并将其归并排序,再统计两个子数组之间的逆序对个数,并进行归并排序。
为什么是要排序?因为计算了一个逆序对之后,就要打乱顺序,防止之后重复计算。
代码实现:
#include<iostream> using namespace std; //数组中的逆序对 long long GetMergePairsBetween(int* arr,int* copy,int start,int mid,int end) { //合并两个子数组,并计算逆序对个数 int final1 = mid;//第一个数组的最后一位 int final2 = end;//第二个数组的最后一位 int index = end;//辅助数组的最后一位 long long count = 0; while(final1 >= start && final2 >= mid+1)//两个数组都没有处理完 { if(arr[final1] > arr[final2]) { //如果第一个数组的元素大于第二个数组的任何元素, //则第一个数组的元素一定大于第个数组中final2之前的所有元素 count += (final2 - mid); //将final1处的元素拷贝至copy数组 //index和final1都向前移动 copy[index--] = arr[final1--]; } else { //第一个数组的元素小于第二个数组的元素 //第二个数组的元素拷贝至copy数组 //并将index和final2前移 copy[index--] = arr[final2--]; } } while(final1 >= start)//第一个数组的元素没有处理完 { copy[index--] = arr[final1--]; } while(final2 >= mid + 1)//第一个数组的元素没有处理完 { copy[index--] = arr[final2--]; } for(int i = end; i > index;i--) arr[i] = copy[i]; return count; } long long GetMergePairs(int* arr,int* copy,int start,int end) { long long ret = 0; if(start < end) { int mid = start + ((end - start)>>1); ret += GetMergePairs(arr,copy,start,mid); ret += GetMergePairs(arr,copy,mid+1,end); ret += GetMergePairsBetween(arr,copy,start,mid,end); } return ret; } long long GetTotalPairs(int arr[],int n) { if(arr == NULL || n < 2) return 0; int* copy = new int ; long long sum = GetMergePairs(arr,copy,0,n-1); delete[] copy; return sum; } int main() { int arr[] = {7,5,6,4}; int ret = GetTotalPairs(arr,sizeof(arr)/sizeof(arr[0])); cout<<ret<<endl; system("pause"); return 0; }
相关文章推荐
- 一个关于if else容易迷惑的问题
- 一道sql面试题附答案
- C# 超高面试题收集整理
- 14 个折磨人的 JavaScript 面试题
- 人人网javascript面试题 可以提前实现下
- JS面试题---关于算法台阶的问题
- PHP中设置一个严格30分钟过期Session面试题的4种答案
- 举例讲解C语言对归并排序算法的基础使用
- C语言数据结构 链表与归并排序实例详解
- 经典的20道AJAX面试题(必知必会)
- java实现归并排序算法
- 据说是雅虎的一份PHP面试题附答案
- php牛逼的面试题分享
- 一套比较完整的javascript面试题(部分答案)
- 10个经典的Java main方法面试题
- 小米公司JavaScript面试题
- JavaScript面试题大全(推荐)
- 超级全面的PHP面试题整理集合第1/2页
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- C++实现自底向上的归并排序算法