数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 
输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5



输入例子:
1,2,3,4,5,6,7,0

输出例子:

7

/*归并排序的改进,把数据分成前后两个数组(递归分到每个数组仅有一个数据项),
合并数组,合并时,出现前面的数组值array[i]大于后面数组值array[j]时;则前面
数组array[i]~array[mid]都是大于array[j]的,count += mid+1 - i
参考剑指Offer,但是感觉剑指Offer归并过程少了一步拷贝过程。
还有就是测试用例输出结果比较大,对每次返回的count mod(1000000007)求余
*/
 
public class Solution {
     public int InversePairs( int [] array) {
         if (array== null ||array.length== 0 )
         {
             return 0 ;
         }
         int [] copy =  new int [array.length];
         for ( int i= 0 ;i<array.length;i++)
         {
             copy[i] = array[i];
         }
         int count = InversePairsCore(array,copy, 0 ,array.length- 1 ); //数值过大求余
         return count;
         
     }
     private int InversePairsCore( int [] array, int [] copy, int low, int high)
     {
         if (low==high)
         {
             return 0 ;
         }
         int mid = (low+high)>> 1 ;
         int leftCount = InversePairsCore(array,copy,low,mid)% 1000000007 ;
         int rightCount = InversePairsCore(array,copy,mid+ 1 ,high)% 1000000007 ;
         int count =  0 ;
         int i=mid;
         int j=high;
         int locCopy = high;
         while (i>=low&&j>mid)
         {
             if (array[i]>array[j])
             {
                 count += j-mid;
                 copy[locCopy--] = array[i--];
                 if (count>= 1000000007 ) //数值过大求余
                 {
                     count%= 1000000007 ;
                 }
             }
             else
             {
                 copy[locCopy--] = array[j--];
             }
         }
         for (;i>=low;i--)
         {
             copy[locCopy--]=array[i];
         }
         for (;j>mid;j--)
         {
             copy[locCopy--]=array[j];
         }
         for ( int s=low;s<=high;s++)
         {
             array[s] = copy[s];
         }
         return (leftCount+rightCount+count)% 1000000007 ;
     }
}

参考《剑指offer》用归并排序的思想, 时间复杂度O(nlogn)

代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
int InversePairs(vector< int > data) {
         int length  = data.size();
         return mergeSort(data, 0, length-1);
     }
 
     int mergeSort(vector< int >& data,  int start,  int end) {
         // 递归终止条件
         if (start >= end) {
             return 0;
         }
 
         // 递归
         int mid = (start + end) / 2;
         int leftCounts = mergeSort(data, start, mid);
         int rightCounts = mergeSort(data, mid+1, end);
 
         // 归并排序,并计算本次逆序对数
         vector< int > copy(data);  // 数组副本,用于归并排序
         int foreIdx = mid;       // 前半部分的指标
         int backIdx = end;       // 后半部分的指标
         int counts = 0;          // 记录本次逆序对数
         int idxCopy = end;       // 辅助数组的下标
         while (foreIdx>=start && backIdx >= mid+1) {
             if (data[foreIdx] > data[backIdx]) {
                 copy[idxCopy--] = data[foreIdx--];
                 counts += backIdx - mid;
             else {
                 copy[idxCopy--] = data[backIdx--];
             }
         }
         while (foreIdx >= start) {
             copy[idxCopy--] = data[foreIdx--];
         }
         while (backIdx >= mid+1) {
             copy[idxCopy--] = data[backIdx--];
         }
         for ( int i=start; i<=end; i++) {
             data[i] = copy[i];
         }
 
         return (leftCounts+rightCounts+counts);
     }


Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值