题目链接

https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5

题意

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007。题目保证输入的数组中没有的相同的数字。

解题思路

在归并排序的过程中计逆序对。时间复杂度O(nlogn),空间复杂度O(n)。

  • 将数组从中间分成前后两个数组(递归到只有一个数据项)。注意数组都是含该数组首尾坐标元素的。
  • 然后合并并排序两个数组,排序结果在copy数组。具体地,i、j指针从两个数组后向前遍历,将大的拷贝到copy数组(copy数组从后往前填)。最后剩下的数组的剩下的部分一并拷贝到copy数组
  • 在合并过程中计逆序对,若i指向的元素大于j,则count+=j-mid;即mid+1到j的元素都比i指向的元素小。
  • 最终返回的count是两个数组内部的逆序对 + 合并过程中的逆序对数(即上一条)。

注意

  • 每次递归传参copy和array换位置(滚动数组)。保证(左右子数组返回后)开始时data[l,mid]和data[mid+1,r]内部有序,结束时copy[l,r]内部有序。
  • size_t 是>=0 所以当i=0,i--,i会等于一个较大正数而不是-1,仍满足while(i>=l),使得程序错误。
  • cnt+=(j-mid)%1000000007应改为cnt=(cnt+(j-mid))%1000000007

代码

class Solution {
public:
int InversePairs(vector<int> data) {
int cnt=0;
if(!data.empty()){
vector<int> copy;
for(auto it=data.begin();it!=data.end();++it){
copy.push_back(*it);
}
cnt=inversePairCnt(data,copy,0,data.size()-1);
}
return cnt;
}
private:
int inversePairCnt(vector<int>& data,vector<int>& copy,int l,int r){
if(l==r){
return 0;
}
int mid=(l+r)>>1;
int leftCnt=inversePairCnt(copy,data,l,mid);
int rightCnt=inversePairCnt(copy,data,mid+1,r);
//开始:此时data[l,mid]和data[mid+1,r]内部有序,copy[l,mid]和copy[mid+1,r]内部无序 int i=mid;
int j=r;
int copyIndex=r;
int cnt=0;
while(i>=l&&j>mid){
if(data[j]>data[i]){
copy[copyIndex--]=data[j--];
}
else{
cnt=(cnt+(j-mid))%1000000007;//
copy[copyIndex--]=data[i--];
}
}
while(i>=l){//
copy[copyIndex--]=data[i--];
}
while(j>mid){
copy[copyIndex--]=data[j--];
}
//结束:此时copy[l,r]内部有序,data[l,r]内部无序
return (leftCnt+rightCnt+cnt)%1000000007;
}
};

[剑指offer]51-数组中的逆序对(归并排序)的更多相关文章

  1. 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组

    剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...

  2. 【Java】 剑指offer(51)数组中的逆序对

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成 ...

  3. 微软面试题:剑指 Offer 51. 数组中的逆序对 Hard 出现次数:3

    题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. 输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...

  4. 【剑指offer】数组中的逆序对

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/27520535 转载请注明出处:http:// ...

  5. Go语言实现:【剑指offer】数组中的逆序对

    该题目来源于牛客网<剑指offer>专题. 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对10000 ...

  6. 【剑指offer】数组中的逆序对。C++实现

    原创文章,转载请注明出处! 博客文章索引地址 博客文章中代码的github地址 # 题目 # 思路 基于归并排序的思想统计逆序对:先把数组分割成子数组,再子数组合并的过程中统计逆序对的数目.统计逆序对 ...

  7. 剑指Offer 35. 数组中的逆序对 (数组)

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

  8. [剑指Offer] 35.数组中的逆序对

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

  9. 剑指offer:数组中的逆序对

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

  10. 剑指offer——54数组中的逆序对

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

随机推荐

  1. JEECG前后端分离UI框架实战版本抢先体验(ng2-admin+Angular4+AdminLTE+WebStorm)

    JEECG前后端分离UI框架实战版本 - 抢先体验 (ng2-admin+Angular4+AdminLTE) 关键词: ng2-admin.Angular4.AdminLTE.Nodejs.Jeec ...

  2. GCD 常用API 总结

    dispatch_sync:同步操作,会阻塞当前线程 dispatch_async:普通的异步操作,也就是在指定的队列中添加一个block操作,不会阻塞当前线程 dispatch_group_asyn ...

  3. 使用Docker搭建Tomcat运行环境

    1 准备宿主系统 准备一个 CentOS 7操作系统,具体要求如下: 必须是 64 位操作系统 建议内核在 3.8 以上 通过以下命令查看您的 CentOS 内核: # uname -r 2 安装Do ...

  4. Haskell语言学习笔记(89)Unicode UTF8

    unicode-show $ cabal install unicode-show Installed unicode-show-0.1.0.2 Prelude> :m +Text.Show.U ...

  5. 转: CSS3 @media 用法总结

    一.首先是<meta>标签 <meta name="viewport" content="width=device-width, initial-sca ...

  6. Android DevArt3:SingleTask启动模式探究:首先从MainActivity启动案例入口AActivity,并在A中启动BActivity,从B启动CActivity, 再从C中又启动AActivity, 最后在A中启动B,现在按两次back键,然后回到的是哪个Activity? 答案是,回到MainActivity。

    SingleTask启动模式探究 GitHub如题:首先从MainActivity启动案例入口AActivity,并在A中启动BActivity,从B启动CActivity,再从C中又启动AActiv ...

  7. Javascript中call、apply之我见

    一.call和apply定义. 1.Call 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 参数 thisObj 可选项.将被用作当前对象的对象. arg ...

  8. Uni2D 入门 -- Animation Clip 和 Animation API

    转载 csdn kakashi8841 http://blog.csdn.net/kakashi8841/article/details/17599505 Animation Clip 一个anima ...

  9. hdu1799-循环多少次?-(组合恒等式)

    循环多少次? Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  10. Oracle监听程序未启动或数据库服务未注册到该监听

    oracle新建数据库的时候提示Could not find appropriate listener for this database要做的操作如下: 1.查看netmanager里面的liste ...