逆序對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.pswp.cn/news/534875.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534875.shtml
英文地址,請注明出處:http://en.pswp.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和剛…