题目:

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

输入描述:

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

数据范围:

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

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

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

分析:

可以从头扫描整个数组,每扫描到一个数字,就去计算后面的数字有多少比它小,这样操作的话时间复杂度是O(n^2),应该会超时。

我们可以利用归并排序时合并两个有序的数组时候,更快的求得每次合并时的逆序对。

例如合并[5,7]和[4,6]时从两个数组后面开始比较,选出较大的元素。

因为7>6,所以7一定大于第二个数组剩下的所有元素,因为数组本身是有序的,可以立刻得到逆序对的个数,当后面的元素大时,不需要统计逆序对的个数,因为此时要大于前面剩下的所有元素,不构成逆序对。基于这种方法,时间复杂度控制在O(nlogn)。

程序:

C++

class Solution {
public:
int InversePairs(vector<int> data) {
return mergesort(data, , data.size()-)%;
}
long long mymerge(vector<int> &vec, int left, int mid, int right){
vector<int> temp(right-left+,);
int index = right-left;
long long countnum = ;
int i = mid;
int j = right;
while(i >= left && j >= mid+){
if(vec[i] > vec[j]){
countnum += (j-mid);
temp[index--] = vec[i--];
}
else{
temp[index--] = vec[j--];
}
}
while(i >= left)
temp[index--] = vec[i--];
while(j >= mid+)
temp[index--] = vec[j--];
for(int i = ; i < temp.size(); ++i)
vec[i+left] = temp[i];
return countnum;
}
long long mergesort(vector<int> &vec, int left, int right){
if(left >= right)
return ;
int mid = (left + right) / ;
long long leftCount = mergesort(vec, left, mid);
long long rightCount = mergesort(vec, mid+, right);
long long res = mymerge(vec, left, mid, right);
return res + leftCount + rightCount;
}
};

Java

public class Solution {
public int InversePairs(int [] array) {
return (int)(mergesort(array, , array.length-)%);
}
public static long mymerge(int [] array, int left, int mid, int right){
int[] temp = new int[right-left+];
int index = right-left;
long countnum = ;
int i = mid;
int j = right;
while(i >= left && j >= mid+){
if(array[i] > array[j]){
countnum += (j-mid);
temp[index--] = array[i--];
}
else{
temp[index--] = array[j--];
}
}
while(i >= left)
temp[index--] = array[i--];
while(j >= mid+)
temp[index--] = array[j--];
for(i = ; i < temp.length; ++i)
array[i+left] = temp[i];
return countnum;
}
public static long mergesort(int [] array, int left, int right){
if(left >= right)
return ;
int mid = (left + right) / ;
long leftCount = mergesort(array, left, mid);
long rightCount = mergesort(array, mid+, right);
long res = mymerge(array, left, mid, right);
return res + leftCount + rightCount;
}
}

剑指Offer-34.数组中的逆序对(C++/Java)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  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. Java连接MySQL简单步骤及常见问题解析

    这篇文章跟读者们介绍Java语言如何连接到MySQL数据库相关操作,及FAQ(Frequently Asked Questions)介绍. 选择工具和准备数据集 IDE:Eclipse 数据库:使用的 ...

  2. git .gitignore详解

    1.最近使用git又遇到一个陷阱: 场景:A和B使用的不同的编译器做的同一个解决方案下的不同的项目工程,刚开始没考虑到版本问题,后来发现A上传的csproj在B需要做很麻烦修改才能打开,后来想到各自用 ...

  3. word转HTML部署到服务器不能运行

    已经解决.在网上找的:网址:http://blog.sina.com.cn/s/blog_852ca01901016lyz.html远程调用Excel.Word.PowerPoint,服务器端设置(2 ...

  4. 【Canvas真好玩】从黑客帝国开始

    前言 笔者之前有一段时间一直在学习Canvas相关的技术知识点,通过参考网上的一些资料文章,学着利用简单的数学和物理知识点实现了一些比较有趣的动画效果,最近刚好翻看到以前的代码,所以这次将这些代码实践 ...

  5. 学习笔记之vim的使用

    很多刚学习linux编程的人总是对vim有一种恐惧,我自己就是这么回事的. 可是当你努力的去尝试学习使用后,才发现它的精髓所在. 在我看来,让vim变得好用的前提是要安装两个插件,ctags和tagl ...

  6. windows使用docker运行mysql等工具(二)安装运行mysql

    今天接着上一篇的内容继续来学习安装运行mysql.建议先阅读第一篇:windows安装docker 一 查看mysql版本 如果想知道mysql镜像具体有哪几个版本,需要去docker hub查看. ...

  7. python中字符串常见操作(二)

    # 可迭代对象有:字典,列表,元组,字符串,集合 str1 = '192.168.1.1' str2 = 'as df gh jk' str3 = '小李子' str4 = ['aa','bb','c ...

  8. MySQL-配置环境变量及修改密码(附-mysql安装教程)

    MySQL-配置环境变量和修改密码 mysql的安装教程:链接:https://pan.baidu.com/s/1rrPT2X0yRF58kN8jZZx-Mg 密码:55dh 一. 闪退问题 1.1. ...

  9. 第六天、用户、组、权限、grep

    第六天.用户.组.权限.grep 权限总结表 操作 源目录权限 文件权限 目标目录权限 rm删文件 wx - - mv改名 wx - - mv移动文件 wx r wx cp复制文件 x r wx &g ...

  10. (Codeforce)Correct Solution?

    One cold winter evening Alice and her older brother Bob was sitting at home near the fireplace and g ...