问题描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 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. 使用ANTLR解析CSV和JSON

    再续 ANTLR专题 ,有了前面的基础,下面开始用ANTLR写一些有趣且实用的程序. CSV和JSON这两种数据格式对软件开发人员来说最熟悉不过了,一般读写CSV或JSON格式的数据都会借助现成的.比 ...

  2. Go语言核心36讲(Go语言实战与应用二十七)--学习笔记

    49 | 程序性能分析基础(下) 在上一篇文章中,我们围绕着"怎样让程序对 CPU 概要信息进行采样"这一问题进行了探讨,今天,我们再来一起看看它的拓展问题. 知识扩展 问题 1: ...

  3. Linux(Centos) 设置显示vim行号

    1.修改vimrc文件 vim /etc/vimrc 2.在最后添加 set nu 如下图片所示 然后wq! 保存退出

  4. cmake之if

    note if 要 与endif配对使用 语法含义 表达式 含义 if (not expression) 与 expression相反 if (var1 AND var2) var1与var2都为真时 ...

  5. 【LeetCode】874. Walking Robot Simulation 解题报告(Python & C++)

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

  6. 【LeetCode】852. Peak Index in a Mountain Array 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 二分查找 查找最大值位置 寻找第一个下降的位置 日期 ...

  7. .Net Core&Agile Config配置中心

    当服务逐渐的增多,对各服务的配置管理愈加重要,轻量级的配置中心,入手或是搭建都简单许多,基于.net core开发的轻量级配置中心AgileConfig,功能强大,上手简单. https://gith ...

  8. Java Web大作业——编程导航系统

    title: Java Web大作业--编程导航系统 categories: - - 计算机科学 - Java abbrlink: 40bc48a1 date: 2021-12-29 00:37:35 ...

  9. [opencv]调用鼠标事件执行grabcut算法实现阈值分割

    #include<iostream> #include <opencv2/opencv.hpp> #include <math.h> using namespace ...

  10. 【MySQL作业】分组查询 group by 子句——美和易思分组查询应用习题

    点击打开所使用到的数据库>>> 1.按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示: select ...