问题描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1: 输入: [7,5,6,4]
输出: 5
  限制: 0 <= 数组长度 <= 50000

这道题和leetcode 315.计算后面较小数字的个数一样。

代码

首先给一个超出时间限制的暴力解法:

class Solution {
public:
int reversePairs(vector<int>& nums) {
int n = nums.size(),i,j,ans=0;
for(i = 0; i < n; ++i)
{
for(j = i+1; j < n; ++j)
{
if(nums[i] > nums[j])
++ans;
}
}
return ans;
}
};

代码

插入排序,很奇怪,还是超出时间限制

class Solution {
public:
int reversePairs(vector<int>& nums) {
int n = nums.size(),i,ans=0,left,right,middle;
vector<int> tmp;//里面的元素
for(i = n-1; i >= 0; --i)
{
left = 0;right = tmp.size();
while(left < right)
{
middle = left + (right - left)/2;
if(nums[i] > tmp[middle])
{
left = middle + 1;
}
else{
right = middle;
}
}
ans += right;
tmp.insert(tmp.begin()+right,nums[i]);
}
return ans;
}
};

代码

归并排序:

class Solution {
public:
int reversePairs(vector<int>& nums) {
if(nums.size() < 2)return 0;
vector<int> tmp(nums.size());
return merge(nums,0,nums.size()-1,tmp);
}
int merge(vector<int>& nums,int start,int end,vector<int>& tmp)
{
if(start >= end)return 0;
int middle = start + (end - start)/2;
int count = merge(nums,start,middle,tmp) + merge(nums,middle+1,end,tmp);
int left = start,right = middle + 1,i= 0;
//vector<int> tmp(end-start+1);//每次都申请空间浪费时间
while(left <= middle && right <= end)
{
if(nums[left] > nums[right])
{
tmp[i++] = nums[left++];
//如果没有下面的计数就是一个归并排序的操作(从大到小),因为左右两边要合并的数组各自都是从大到小排好序的数组了,一旦出现左边当前数比右边当前数大,则也比右边当前数后面的数都要大,都需要计入逆序
count += end-right+1;
}
else{
tmp[i++] = nums[right++];
}
}
while(left <= middle)tmp[i++] = nums[left++];
while(right <= end)tmp[i++] = nums[right++];
for(i = 0; i < end-start+1; ++i)
nums[start+i] = tmp[i];
return count;
}
};

结果

执行用时 :280 ms, 在所有 C++ 提交中击败了78.32%的用户
内存消耗 :44.4 MB, 在所有 C++ 提交中击败了100.00%的用户

《剑指offer》面试题51. 数组中的逆序对的更多相关文章

  1. 剑指Offer - 九度1348 - 数组中的逆序对

    剑指Offer - 九度1348 - 数组中的逆序对2014-01-30 23:19 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个 ...

  2. 剑指offer(35)数组中的逆序对

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

  3. 【剑指Offer】35、数组中的逆序对

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

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

    数组中任取两个数字,如果前面的数字大于后面的数字称为一个逆序对 如:1,2,1,2,1 有3个逆序对 思路:知道O(N2)肯定是错的.开始想hash,试图找到O(n)的算法,想了很久,找不到.后来想到 ...

  5. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

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

  6. LeetCode 面试题51. 数组中的逆序对

    面试题51. 数组中的逆序对 题目来源:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/ 题目 在数组中的两个数字,如果 ...

  7. 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序

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

  8. 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)

    PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...

  9. 剑指offer 面试题56. 数组中只出现一次的两个数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...

随机推荐

  1. IDEA添加yaml自动补全语法插件

    问题:编写yml文件的时候,系统不能给自动补全 解决办法:File---->Settings---->Plugins---->搜索Spring Assistant x 项目效果预览

  2. MAVEN基础讲解

    MAVEN解决的问题 1.当我们开始一个工程的时候往往需要几十甚至上百个jar包,如果没有一个管理工具的话,结果就是每个都需要自己手动导入工程目录,并且还有可能发生jar包冲突,版本冲突等问题 2.在 ...

  3. Linux(Centos)内存占用过高处理

    查看内存占用最大 ps aux| grep -v "USER" |sort -n -r -k 4 |awk 'NR==1{ print $0}' 命令查看占用内存最大的10个进程 ...

  4. JAVA实现调用默认浏览器打开网页

    /** * @title 使用默认浏览器打开 * @param url 要打开的网址 */ private static void browse2(String url) throws Excepti ...

  5. 人工智能论文解读精选 | PRGC:一种新的联合关系抽取模型

    NLP论文解读 原创•作者 | 小欣   论文标题:PRGC: Potential Relation and Global Correspondence Based Joint Relational ...

  6. 【LeetCode】769. Max Chunks To Make Sorted 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  7. isEmpty 和 isBlank

    <org.apache.commons.lang3.StringUtils> isEmpty系列 StringUtils.isEmpty() ========> StringUtil ...

  8. uniapp跳转webview后H5不执行UniAppJSBridgeReady 回调无用

    开始时我在真机上测试使用 <web-view :src="'/hybrid/html/pages/index/index.html?userInfo='+JSON.stringify( ...

  9. CS5266代替AG9311|Type C转HDMI带PD3.0转换芯片|AG9311替代方案

    ALGOLTEK AG9311是一款带PD3.0 Type C转HDMI的转换芯片,它主要用于usb Type-c拓展坞以及多功能usb Type-c转换器等产品设计当中,台湾瑞奇达新推出的CS526 ...

  10. XML解析的四种方式

    1.说明 XML是EXtensible Markup Language, 即可扩展标记语言, 是一种通用的数据交换格式, 它的平台无关性.语言无关性.系统无关性, 给数据集成与交互带来了极大的方便. ...