逆序对java_逆序对

求逆序对问题用归并排序的时间复杂度比暴力算法更低。

假设有一个数组{8,1,2,5,7,4,3,6}

首先归并排序第一次对数组进行分割      8 1 2 5      7 4 3 6

二次分割      8 1      25      74      36

三次分割      8      1      2      5      7      4      3      6

第一次合并     18     25     74     36      reorder[1]=2, order[1]=2

//用reorder[i]来记录第i次合并中存在的逆序对数,order[i]来记录第i次合并中存在的顺序对数。

第二次合并     1258     3467     reorder[2]=5, order[2]=3

第三次合并     12345678          reorder[3]=6, order[3]=10

那么数组{8,1,2,5,7,4,3,6}中存在的逆序对就等于reorder[1]+reorder[2]+reorder[3]=13

将数组{8,1,2,5,7,4,3,6}每2^2个为一组进行翻转{5,2,1,8,6,3,4,7}

首先归并排序第一次对数组进行分割      5 2 1 8      6 3 4 7

二次分割      5 2      18      63      47

三次分割      5      2      1      8      6     3      4      7

第一次合并     25     18    36     47      reorder[1]=2, order[1]=2

第二次合并     1258     3467     reorder[2]=3, order[2]=5

第三次合并     12345678          reorder[3]=6, order[3]=10

那么数组{5,2,1,8,6,3,4,7}中存在的逆序对就等于reorder[1]+reorder[2]+reorder[3]=11

由此我们可以观察到对数组每2^2个进行翻转时,reorder[1]和order[1]进行了互换,reorder[2]和order[2]亦是如此。

所以对数组每2^i个进行翻转时,我们可以把1~i的reorder和order数组元素互换即可继续通过计算reorder数组的累加和来求得数组的逆序对数。

import java.util.ArrayList;

import java.util.Scanner;

public class Main {

public static void main(String[] args)

{

Scanner sc = new Scanner(System.in);

int n = sc.nextInt();

int N = 1 << n;

int[] a = new int[N];

int[] b = new int[N];//用来存储数组的逆序,对逆序的数组进行一次归并排序可以直接得到order数组

int[] order = new int[n + 1];//为了便于计算,所以设置order下标是1~n,因此数组大小为n+1

int[] reorder = new int[n + 1];

for (int i = 0; i < N; i++)

{

a[i] = sc.nextInt();

b[N - i - 1] = a[i];

}

MergeSort(a, 0, N - 1, reorder, n);//对整个数组进行归并排序,n表示对reorder[1]~reorder[n]进行初始化

MergeSort(b, 0, N - 1, order, n);//对整个逆序数组进行归并排序,完成对order[1]~order[n]的初始化

int m = sc.nextInt();

while(m-- > 0)

{

int count = 0;

int q = sc.nextInt();

for (int i = 1; i <= q; i++) //像之前讲的,将1~q的reorder[i]和order[i]进行互换

{

int temp = reorder[i];

reorder[i] = order[i];

order[i] = temp;

}

for (int i = 1; i <= n; i++)

{

count+= reorder[i];//累加reorder数组,求得对数组中每2^q个元素进行翻转后的逆序对数

}

System.out.println(count);

}

}

public static void MergeSort(int[] a , int left, int right, int[] reorder, int index)

{

if(left < right)

{

int mid = (right + left) / 2;

MergeSort(a, left, mid, reorder,index - 1);

MergeSort(a, mid + 1, right, reorder,index -1);

if(a[mid] > a[mid+1])//如果a[mid]<=a[mid+1],则原数组有序,不需要合并

Merge(a, left, right,reorder, index);

}

}

public static void Merge(int[] a, int left, int right,int[] reorder, int index)//index表示对reorder[index]进行初始化

{

int mid = (right + left) / 2;

int Length1 = mid - left + 1;

int Length2 = right - mid;

int[] l = new int[Length1];//存储a[left]~a[mid]

int[] r = new int[Length2];//存储a[mid+1]~a[right]

System.arraycopy(a, left, l, 0, Length1);//对l进行初始化

System.arraycopy(a, mid + 1, r, 0, Length2);//对r进行初始化

int i = 0;

int j = 0;

int c= 0;

int k = left;

while(i < Length1 && j < Length2)

{

if(l[i] <= r[j])

{

a[k] = l[i];

i++;

}

else

{

a[k] = r[j];

j++;

c += Length1 - i;//当l[i]>r[j]时,因为l是递增序列,所以l[i]~l[Length1-1]均>r[j],所以有Length1-i个元素大于r[j]

}

k++;

}

System.arraycopy(l, i, a, k, Length1 - i);//前面归并排序MergeSort中调用Merge合并的条件是a[mid]>a[mid+1],因为当a[mid]<=a[mid+1]时说明原数组有序,无需合并。l[Length1-1]>r[Length2-1],即l数组的最大值大于r数组的最大值,所以当r中的数全部进入a数组后,l数组中仍有剩余。

reorder[index] += c;

}

}

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

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

相关文章

python123测验9程序题答案_Django ORM 练习题及答案_python_脚本之家

1.modles中表结构#出版社class Publisher(models.Model):name models.CharField(max_length32)city models.CharField(max_length32)def __str__(self):return "".format(self.id, self.name)#书籍class Book(models.Model):title models.CharField(max_length32)…

java父类shape_为什么该父类无法调用其子类.__ShapeCircle_public_perimeter_getType_shapej__169IT.COM...

子类:public class ShapeCircle extends Shape{protected double r;public ShapeCircle(){setside(0.0);}public ShapeCircle(double r){setside(r);}public void setside(double r){this.rr;}public double perimeter(){return Math.PI*2*r;}public String getType(){return &…

python中双冒号的作用_python中双冒号

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

java电子通讯录毕业设计_(C)JAVA001电子通讯录(带系统托盘)

打开Server Socket,创建一个服务器型套接字和一个普通套接字&#xff0c;服务器型套接字在指定端口为客户端请求的Socket 服务&#xff1b;? 使用ServerSocket类的accept()方法使服务器型套接字处于监听状态并把监听结果返回给普通套接字&#xff1b;? 为该普通套接字创建输入…

python进行数据分析需要安装哪两个库_对Python进行数据分析_关于Package的安装问题...

一、为什么要使用Python进行数据分析&#xff1f;python拥有一个巨大的活跃的科学计算社区&#xff0c;拥有不断改良的库&#xff0c;能够轻松的集成C,C,Fortran代码(Cython项目)&#xff0c;可以同时用于研究和原型的构建以及生产系统的构建。二、Python的优势与劣势&#xff…

java orcl自动_Oracle自动生成编号

祝大家新年快乐&#xff0c;有任何问题可与我联系&#xff1a;今天用JAVA向Oracle数据库中插数据时&#xff0c;每次都要去计算ID&#xff0c;觉得好麻烦&#xff0c;于是想到了用数据库自带的ID来做&#xff0c;具体如下&#xff1a;1、首先得创建一序列序列(SEQUENCE)序列是一…

bat批处理执行python_.bat批处理添加Python任务

一、常用命令含义例一、多进程python 任务 -- start 命令echo offstart python C:\Users\ntitled\n\update_restt\test_bat.pypython C:\Users\ntitled\iin\update_restt\test_bat.pypython C:\Users\ntitled\jin\update_restt\test_bat2.pyexit1、它的作用是让执行窗口中不显…

import java.awt.BorderLayout;_Swing-布局管理器之BorderLayout(边界布局)-入门

边界布局管理器(BorderLayout)把容器的的布局分为五个位置&#xff1a;CENTER、EAST、WEST、NORTH、SOUTH。依次对应为&#xff1a;上北(NORTH)、下南(SOUTH)、左西(WEST)、右东(EAST)&#xff0c;中(CENTER)&#xff0c;如下图所示。特征&#xff1a;l 可以把组件放在这五个位…

一分钟学会python编程_用Python教你一分钟检验出来!不用群发_编程语言_Python课程_Python教程_课课家...

Python大法已经被网友们玩儿的出神入化了, 最近有网友用Python写了一个脚本, 这个脚本能够自动检测你的微信好友中谁把你删除了? 而且不需要群发消息, 整个过程好友们是完全不知情的。使用范围Mac和Linux经过测试, 确认可用, Windows等待大家的测试反馈, 可以在评论中反馈哦~~…

java 建造者实际中的用法_java中j建造者模式详解和使用方法

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。介绍意图&#xff1a;将一个复杂的…

python垃圾回收机制为什么标记能解决循环引用问题_python 关于循环引用以及标记清除的问题...

1 在循环引用的情况下,引用计数就不好事了,这时候就需要用到标记清除循环引用的危害: 会造成内存溢出,因为循环引用计数不可能为零解决方法:标记清除2 关于标记清除的效率问题(低)引用计数引用一次就加1,值减到0以后就应该被回收,那这里就产生了一个问题cpython的垃圾回收机制不…

jsp测试mysql_Jsp登陆与MySQL对接验证

最近在做一个Web项目&#xff0c;账户登陆验证是Web项目中必不可少的环节&#xff0c;所以需要阶段性的记录&#xff0c;帮助自己更好的掌握其中的知识。Jsp登陆涉及到POST方法参数获取&#xff0c;以及MySQL数据库信息的获取。可能因为自己是新手&#xff0c;刚开始写的项目有…

数据归一化处理方法_科研常用的实验数据分析与处理方法

科研常用的实验数据分析与处理方法对于每个科研工作者而言&#xff0c;对实验数据进行处理是在开始论文写作之前十分常见的工作之一。但是&#xff0c;常见的数据分析方法有哪些呢&#xff1f;常用的数据分析方法有&#xff1a;聚类分析、因子分析、相关分析、对应分析、回归分…

java专业术语 ioc_什么叫IOC(编程术语

IoC就是Inversion of Control&#xff0c;控制反转。在Java开发中&#xff0c;IoC意味着将你设计好的类交给系统去控制&#xff0c;而不是在你的类内部控制。这称为控制反转。下面我们以几个例子来说明什么是IoC假设我们要设计一个Girl和一个Boy类&#xff0c;其中Girl有kiss方…

python群控模拟安卓系统_手机群控脚本通用版安装包下载-手机群控脚本通用版apk(云控平板)v1.0.01真机模拟版_新绿资源网...

手机群控脚本通用版apk是一款真机模拟云控平板应用&#xff0c;支持工作室批量挂机搬砖、直播刷人气点赞、云手机试玩项目、吸粉营销、智能引流赚钱等功能&#xff0c;无需多部手机&#xff0c;一个APP控制上万部手机&#xff0c;下载安装吧&#xff01;应用介绍&#xff1a;云…

java jsonobject.parse_JSON.parseObject的几种用法

import com.alibaba.fastjson.JSONObject;一.result格式:{"success":"true";"returnAddress":"123"}JSONObject jsonObjectJSON.parseObject(result); //转换成objectjsonObject.getString("returnAddress") //获取object中…

信息系统项目管理师_信息系统项目管理师通过率是多少?

答&#xff1a;信息系统项目管理师考试每个地区的通过率都是不一样的&#xff0c;一般全国在10%-20%左右&#xff0c;这个20%的通过率是按参考人数作为统计&#xff0c;就是除去了那些报名了但是没去参加考试的考生&#xff0c;如果算上所有报名考生的通过率数据&#xff0c;那…

类型“unknown”上不存在属性“foreach”_JavaScript红宝书第四版精简解析系列--映射Map数据类型...

Map数据类型顾名思义也就是映射类型,包含一个[[Entries]]私有特性我们可以使用一个二维数组作为初始值const map1 new Map([[1, 1],[2, 2],[3, 3],]); console.log("Map数据类型>", map1);当然也可以使用迭代器进行初始化const map2 new Map({[Symbol.iterator]…

java面试笔试题整理(学习java基础理论最好的资料)_2020Java笔试/面试题(持续收集整理更新)...

说明&#xff1a;java本篇用于收集知识点方便随时巩固&#xff0c;持续更新与纠错。数组关于JDK版本&#xff0c;若无特殊说明&#xff0c;默认为JDK 1.8,。缓存关于JVM版本&#xff0c;若无特殊说明&#xff0c;默认为 HotSpot。安全目录数据结构1、Java 基础1.1 Java中的基本…

JAVA服务器没回应_Java如何面对无服务器的挑战?

这是来自jaxcenter组织的一个讨论&#xff0c;谈论了Java在无服务器浪潮冲击下面临的机会和挑战。下面摘录主要部分&#xff1a;Spring推动者Pivotal有一个名为 Riff的函数即服务平台&#xff0c;它是一个开源的、Apache 2许可的、函数即服务平台&#xff0c;基于Kubernetes和刚…