剑指offer-35-数组中的逆序对

数组中的逆序对_牛客网

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

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

数据范围:

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

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

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

示例1
输入
复制
1,2,3,4,5,6,7,0
输出
复制
7

错误思路

自己做的时候一直想用dp的方法来做:用dp(i)表示以i开头的逆序对,然后在获得dp(j)(j=i-1)的时候,寻找序号大于j的第一个小于等于array(j)的序号i,dp(j) = dp(i)+if(array(i)<array(j)),但是这样的想法是不对的,用这样的动态规划转移方程式会漏掉一部分数据,因为在i之后可能会存在大于array(i)但小于array(j)的数,这部分数字和array(j)可以组成逆序对,但是却不会被计算在dp(j)中,所以这个思路是有问题的。

而且动态规划是用来求最值问题的方法,但是这道题目明显不是让我们求最大值和最小值的,从原则上来说,这种思路就是错误,一定要摒弃掉。

正确思路

所以不得已只能用大家提供的归并排序的思路来做这道题目以实现o(nlogn)的复杂度。 在归并排序的过程中 后一个数组的数如小于前一个数组的数,则一定能够构成逆序对且逆序对的数目可计算,因为待归并的两个数组提前已经归并排序过,所以不会出现像前面那样少统计或者多统计的情况出现。 思路:[A,B]中的逆序对=[A]的逆序对+[B]中的逆序对+将A,B混排在一起的逆序对 而将A,B混排在

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

小白刷剑指offer 文章被收录于专栏

跟着小白一起刷剑指offer,通过讨论加深印象吧~ 没有人不学习就能够掌握知识,知识就是需要学习的~

全部评论
你好,对1000000007求模的时候,为什么要在每一次统计出次数的时候而不是在return中??我也试过了,确实,在return中是通不过所有的测试用例的!这是为什么呢?
8
送花
回复
分享
发布于 2019-12-06 22:07
厉害啊,每次都在解析中出现
1
送花
回复
分享
发布于 2020-02-21 14:56
秋招专场
校招火热招聘中
官网直投
超时了。。。复制源码也没过
1
送花
回复
分享
发布于 2021-02-09 15:46
[A,B]中的逆序对=[A]的逆序对+[B]中的逆序对+将A,B混排在一起的逆序对 [A,B]中的逆序对 不等于 将A,B混排在一起的逆序对??? 将A,B混排在一起的逆序对 这是什么意思???
点赞
送花
回复
分享
发布于 2019-11-10 15:11
[A,B]中的逆序对=[A]的逆序对+[B]中的逆序对+将A,B混排在一起的逆序对,[A,B]中的逆序对 不等于 将A,B混排在一起的逆序对??? 将A,B混排在一起的逆序对 这是什么意思???
点赞
送花
回复
分享
发布于 2019-11-10 15:12
我可能没有写清楚,稍等我补充整理一下。 假设我们要求解[A,B]这样的数组的逆序对,其中[A]是一个已经排序的子数组,其中的逆序对为AA,[B]是另外一个已经排序的子数组,其中的逆序对为BB,然后我们用归并排序将A和B进行排序,此时发现可组成的逆序对为CC,[A B]这个数组 中的逆序对数目就=AA+BB+CC
点赞
送花
回复
分享
发布于 2019-11-14 20:34
为什么现在AC不了了。。。有盆友这种情况吗
点赞
送花
回复
分享
发布于 2020-03-08 10:18
while(i<= mid) temp[k++] = array[i++]; while(j<=end) temp[k++] = array[j++];这两步怎么理解
点赞
送花
回复
分享
发布于 2020-03-10 20:21
你好,我有个点不明白 cnt = (cnt + (mid-i+1))%1000000007;这句话是什么意思呢(mid-i+1)是啥QAQ
点赞
送花
回复
分享
发布于 2020-04-12 17:04
为什么使用双重循环,进行枚举,通过不了? if(array == null) return 0; int p = 0; for(int i = 0; i < array.length-1; i++){ for(int j = 1; j < array.length; j++){ if(array[i] > array[j]) p++; } } return p%1000000007;
点赞
送花
回复
分享
发布于 2020-05-05 12:18
大佬,永远都能看到你的题解
点赞
送花
回复
分享
发布于 2020-06-13 18:06
哈哈哈
点赞
送花
回复
分享
发布于 2020-07-23 22:34
怎么得到的cnt ,,,,在merge中有没有返回cnt
点赞
送花
回复
分享
发布于 2020-07-24 09:20
有个问题,cnt = (cnt + (mid-i+1))%1000000007这句可以换成cnt += mid - i + 1,然后在return的时候再做取模,返回cnt % 100000007;吗? 为什么我这么写答案是错的,一定要在递归统计次数的时候取模才行吗?
点赞
送花
回复
分享
发布于 2020-11-18 10:54
//如果前面的元素大于后面的,那么在前面元素之后的元素都能和后面的元素构成逆序对 这句话怎么理解,各位大佬帮帮忙
点赞
送花
回复
分享
发布于 2021-02-21 12:12
为什么我把cnt从private换成static就不通过呢?
点赞
送花
回复
分享
发布于 2021-03-20 21:23
个人觉得动态规划可以,dp[i] = dp[i-1] + count,count为arr[0]到arr[i-1]中比arr[i]大的个数,只是这样复杂度太大了
点赞
送花
回复
分享
发布于 2021-03-26 11:00

相关推荐

45 2 评论
分享
牛客网
牛客企业服务