题目描述

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

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

数据范围:

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

题目分析

第一反应是采用暴力解法,不过肯定会超时,所以我们需要用时间复杂度更低的解法.

说实话这道题有点难,我也是参考剑指offer上的。那么难点在哪呢?

  • 难点一:要想到基于归并排序去解决。
  • 难点二:参数的问题,这里很巧妙地用了一个copy数组作为data参数。
  • 难点三:合并时,count如何计数。

不过只要注意这些小细节,多花点时间想明白还是能做出来的.

代码

function InversePairs(data) {
if (!data || data.length < 2) return 0;
const copy = data.slice();
let count = 0;
count = mergeCount(data, copy, 0, data.length - 1);
return count % 1000000007;
}
function mergeCount(data, copy, start, end) {
if (start === end) return 0;
const mid = end - start >> 1,
left = mergeCount(copy, data, start, start + mid), // 注意参数,copy作为data传入
right = mergeCount(copy, data, start + mid + 1, end); // 注意参数,copy作为data传入
let [p, q, count, copyIndex] = [start + mid, end, 0, end];
while (p >= start && q >= start + mid + 1) {
if (data[p] > data[q]) {
copy[copyIndex--] = data[p--];
count = count + q - start - mid;
} else {
copy[copyIndex--] = data[q--];
}
}
while (p >= start) {
copy[copyIndex--] = data[p--];
}
while (q >= start + mid + 1) {
copy[copyIndex--] = data[q--];
}
return count + left + right;
}

最新文章

  1. Yii源码阅读笔记(三十五)
  2. 诚信的cpm广告联盟该怎么选择
  3. 2016 - 3 - 12 SQLite的学习之SQL语言入门
  4. Linux更改主机名--适用于Centos
  5. django 自定义标签和过滤器
  6. CLR via C# 线程基础知识读书笔记
  7. Android SQLite总结[转载]
  8. Windows删除文件时找不到该项目
  9. mysql pdo数据库连接
  10. 单例模式、简单工厂模式、XML解析
  11. eos dapp开发
  12. [HNOI2007]梦幻岛宝珠
  13. 01 Python 逻辑运算
  14. Spring boot http, https
  15. Oracle EBS OPM update material txn
  16. Redis记录-Redis命令
  17. django使用LDAP验证
  18. react学习(一)组件
  19. plsql 连接oracle数据库的2种方式
  20. 换Mac了,迈入了终端的大门

热门文章

  1. web 接口测试入门
  2. javascript 缩写技巧
  3. js字符串转数字(小数),数字转字符串
  4. 关于histry的pushstate 和 popstate事件的应用
  5. a链接QQ客服 在小框口中打开 感觉不错
  6. php 删除空格 和 回车
  7. 手写AVL 树(上)
  8. ES6中Set 和 Map用法
  9. Windows渗透利器之Pentest BOX使用详解(一)
  10. python摸爬滚打之day19----类的约束, 异常处理