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

题目描述

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

解题思路

剑指offer的解法
看到这个题目,我们的第一反应是顺序扫描整个数组。每扫描到一个数组的时候,逐个比较该数字和它后面的数字的大小。如果后面的数字比它小,则这两个数字就组成了一个逆序对。假设数组中含有n个数字。由于每个数字都要和O(n)这个数字比较,因此这个算法的时间复杂度为O(n^2)。
我们以数组{7,5,6,4}为例来分析统计逆序对的过程。每次扫描到一个数字的时候,我们不拿ta和后面的每一个数字作比较,否则时间复杂度就是O(n^2),因此我们可以考虑先比较两个相邻的数字。
在这里插入图片描述
(a) 把长度为4的数组分解成两个长度为2的子数组;
(b) 把长度为2的数组分解成两个成都为1的子数组;
© 把长度为1的子数组 合并、排序并统计逆序对 ;
(d) 把长度为2的子数组合并、排序,并统计逆序对;
在上图(a)和(b)中,我们先把数组分解成两个长度为2的子数组,再把这两个子数组分别拆成两个长度为1的子数组。接下来一边合并相邻的子数组,一边统计逆序对的数目。在第一对长度为1的子数组{7}、{5}中7大于5,因此(7,5)组成一个逆序对。同样在第二对长度为1的子数组{6}、{4}中也有逆序对(6,4)。由于我们已经统计了这两对子数组内部的逆序对,因此需要把这两对子数组 排序 如上图(c)所示, 以免在以后的统计过程中再重复统计。

接下来我们统计两个长度为2的子数组子数组之间的逆序对。合并子数组并统计逆序对的过程如下图如下图所示。

我们先用两个指针分别指向两个子数组的末尾,并每次比较两个指针指向的数字。如果第一个子数组中的数字大于第二个数组中的数字,则构成逆序对,并且逆序对的数目等于第二个子数组中剩余数字的个数,如下图(a)和(c)所示。如果第一个数组的数字小于或等于第二个数组中的数字,则不构成逆序对,如图b所示。每一次比较的时候,我们都把较大的数字从后面往前复制到一个辅助数组中,确保 辅助数组(记为copy) 中的数字是递增排序的。在把较大的数字复制到辅助数组之后,把对应的指针向前移动一位,接下来进行下一轮比较。
在这里插入图片描述
过程:先把数组分割成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序。如果对排序算法很熟悉,我们不难发现这个过程实际上就是归并排序。

代码实现

class Solution {
public:int InversePairs(vector<int> data) {int length=data.size();if(length<=0)return 0;//vector<int> copy=new vector<int>[length];vector<int> copy;for(int i=0;i<length;i++)copy.push_back(data[i]);long long count=InversePairsCore(data,copy,0,length-1);//delete[]copy;return count%1000000007;}long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end){if(start==end){copy[start]=data[start];return 0;}int length=(end-start)/2;long long left=InversePairsCore(copy,data,start,start+length);long long right=InversePairsCore(copy,data,start+length+1,end); int i=start+length;int j=end;int indexcopy=end;long long count=0;while(i>=start&&j>=start+length+1){if(data[i]>data[j]){copy[indexcopy--]=data[i--];count=count+j-start-length;          //count=count+j-(start+length+1)+1;}else{copy[indexcopy--]=data[j--];}          }for(;i>=start;i--)copy[indexcopy--]=data[i];for(;j>=start+length+1;j--)copy[indexcopy--]=data[j];       return left+right+count;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解Linux下通过yum安装Mariadb/MySQL数据库(腾讯云也适用)

1. 安装Mariadb 安装命令 yum -y install mariadb mariadb-server安装完成MariaDB&#xff0c;首先启动MariaDB systemctl start mariadb设置开机启动 systemctl enable mariadbMariaDB的相关简单配置 此命令进入到配置相关界面 mysql_secure_installation首先是设置密码…

【剑指offer】_13 圆圈中最后的数

题目描述 年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱…

【剑指offer】_14 不用加减乘除做加法

题目描述 写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得使用、-、*、/四则运算符号。 解题思路 首先看十进制是如何做的&#xff1a; 5712&#xff0c;三步走 第一步&#xff1a;相加各位的值&#xff0c;不算进位&#xff0c;得到2。 第二步&#x…

海量数据处理(位图和布隆过滤器)

哈希切割 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址&#xff1f; 与上题条件相同&#xff0c;如何找到top K的IP&#xff1f;如何直接用Linux系统命令实现 解决思路 找到出现次数最多的IP地址 要找到前TopK的IP地址&#xff0c;就…

C++11新特性的总结

C11新特性 auto关键字(C11&#xff09;基于范围的for循环(C11&#xff09;. 指针空值nullptr(C11&#xff09;C动态内存管理序列式容器 array forward_list;继承和多态:final overridedelete:不生成默认的成员函数default:强制编译器生成默认的成员函数智能指针:unique_ptr,sh…

详解C++中右值引用

98中的引用 概念特性引用的使用场景三种传参方式效率的比较探索:引用的底层实现方式----->指针 T&------>T* constconst T&---->const T*const 引用和指针的区别 引用的总结 11中的右值引用 为什么要有右值引用 为了提高程序运行效率&#xff0c;C11中引…

C++中的lambda表达式和线程库

98中的一个例子 如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法 #include <algorithm> #include <functional> int main() {int array[] {4,1,8,5,3,7,0,9,2,6};// 默认按照小于比较&#xff0c;排出来结果是升序std::sort(array, a…

文件压缩(Huaffman树的概念及其实现)

什么是压缩 想办法让源文件变得更小并能还原。 为什么要进行文件压缩 文件太大&#xff0c;节省空间提高数据再网络上传输的效率对数据有保护作用—加密 文件压缩的分类 无损压缩 源文件被压缩后&#xff0c;通过解压缩能够还原成和源文件完全相同的格式 有损压缩 解压缩之…

详解STL中的空间配置器(SGI版本)

空间配置器 1.什么是空间配置器 为各个容器高效的管理空间(空间的申请与回收)的 2.为什么需要空间配置器 各种容器----->可以存放元素---->底层需要空间 new 申请空间 operator new ---->malloc调用构造函数------完成对象的构造 动态内存管理总结 前面的容器…

【剑指offer】_15数组中重复的数字

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的&#xff0c;但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如&#xff0c;如果输入长度为7的数组{2,3,1,0,2,5,3}&#xff0c;那么对应的…

【剑指offer】_16 构建乘积数组

题目描述 给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]A[0]*A[1]*...*A[i-1]*A[i1]*...*A[n-1]。不能使用除法。 解题思路 设有数组大小为5。 对于第一个for循环 第一步&#xff1a;b[0] 1; 第二步&#xff1a;b[1] b[0] * a[0] a[0] 第三…

【剑指offer】_17正则表达式的匹配

题目描述 请实现一个函数用来匹配包括’.‘和*的正则表达式。模式中的字符’.表示任意一个字符&#xff0c;而*表示它前面的字符可以出现任意次&#xff08;包含0次&#xff09;。 在本题中&#xff0c;匹配是指字符串的所有字符匹配整个模式。例如&#xff0c;字符串"aaa…

大四阶段的社会实践的主要目的是_疫情当前,大三大四的学生“很惨”?大一大二的学生也别松懈...

大四毕业生不容易这次疫情对于高校学生而言&#xff0c;可以说是各有各的难处&#xff0c;“这届毕业生很惨”更是屡上热搜。不可否认&#xff0c;大四毕业生确实很不容易&#xff0c;论文答辩、毕业、求职就业等都受到了影响&#xff0c;虽然有困难&#xff0c;但各方都在积极…

【剑指offer】_18 数据流中的中位数

题目描述 如何得到一个数据流中的中位数&#xff1f;如果从数据流中读出奇数个数值&#xff0c;那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值&#xff0c;那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流…

【剑指offer】_19 滑动窗口中的最大值

题目描述 给定一个数组和滑动窗口的大小&#xff0c;找出所有滑动窗口里数值的最大值。例如&#xff0c;如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3&#xff0c;那么一共存在6个滑动窗口&#xff0c;他们的最大值分别为{4,4,6,6,6,5}&#xff1b; 针对数组{2,3,4,2,6,2,…

android 文字反转_多文字共享信息系统

欧阳贵林 www.HeZi.net首发表于2016年03月23日“ 处在信息时代的开端&#xff0c;信息技术不应有特殊的文字性&#xff0c;需要创建多文字共享信息系统&#xff0c;给各国文字一个公平的参与信息与科技创新发展的平台。这是世界的事&#xff0c;更是中国事。”01人类语言语言文…

LeetCode【1--两数之和】 LeetCode【2--两数相加】

两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;你不能重复利用这个数组中同样的元素。 解题思路 直接两…

input数字开头不能为0_李商隐为初恋写诗,每句以数字开头,最后10字一直被仿从未被超越...

上学时&#xff0c;每次写作文&#xff0c;老师总爱在耳边念叨&#xff1a;“你的作文得让阅卷老师看得懂&#xff0c;不然不可能给你高分的&#xff01;”每次听到话&#xff0c;笔者总是用李商隐的诗来和他斗嘴。是的&#xff0c;李商隐的诗作常常是让人读不懂的&#xff0c;…

lsass.exe 当试图更新密码时_“驱动人生”下载器木马再度更新-你应该注意什么?...

360安全大脑监测到通过"驱动人生"供应链攻击传播的挖矿木马在1月30日下午4时左右再次更新。此次更新中&#xff0c;木马在此前抓取系统帐户密码的基础上增加了抓取密码hash值的功能&#xff0c;并试图通过pass the hash攻击进行横向渗透&#xff0c;使得该木马的传播…

LeetCode【3--无重复的最长字串】 LeetCode【4--有序数组中的中位数】

无重复的最长字串 题目描述 给定一个字符串&#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 解题思路 看到这道题&#xff0c;其实就两个步骤&#xff0c;遍历字符串&#xff0c;记录当前字符有没有重复。 重复一般解决就是哈希&#xff0c;这里用个数组表示…