算法筆記_065:分治法求逆序對(Java)

目錄

1 問題描述

2 解決方案

2.1 蠻力法

2.2 分治法(歸并排序)

?


1 問題描述

給定一個隨機數數組,求取這個數組中的逆序對總個數。要求時間效率盡可能高。

?

那么,何為逆序對?

引用自百度百科:

設 A 為一個有 n 個數字的有序集?(n>1),其中所有數字各不相同。
如果存在正整數 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],則 <A[i], A[j]> 這個有序對稱為 A 的一個逆序對,也稱作逆序數。

?例如,數組(3,1,4,5,2)的逆序對有(3,1),(3,2),(4,2),(5,2),共4個。

?

?


2 解決方案

2.1 蠻力法

初步一看,使用蠻力是最直接也最簡單的方法,但是時間效率為O(n^2)

即從第1個元素,開始依次和后面每一個元素進行大小比較,若大于,則逆序對個數加1

具體代碼如下:

package com.liuzhen.systemExe;public class Main{//蠻力法求取數組A中逆序對數public int bruteReverseCount(int[] A) {int result = 0;for(int i = 0;i < A.length;i++) {for(int j = i;j < A.length;j++) {if(A[i] > A[j])result++;}}return result;}//獲取一個隨機數數組public int[] getRandomArray(int n) {int[] result = new int[n];for(int i = 0;i < n;i++) {result[i] = (int)( Math.random() * 50);  //生成0~50之間的隨機數
        }return result;}public static void main(String[] args){long t1 = System.currentTimeMillis();Main test = new Main();int[] A = test.getRandomArray(50000);int result = test.bruteReverseCount(A);long t2 = System.currentTimeMillis();System.out.println("使用蠻力法得到結果:"+result+", 耗時:"+(t2 - t1)+"毫秒");}
}

運行結果(運行3次):

使用蠻力法得到結果:612226389, 耗時:8094毫秒使用蠻力法得到結果:610311942, 耗時:8015毫秒使用蠻力法得到結果:610657465, 耗時:8079毫秒

?

2.2 分治法(歸并排序)?

除了蠻力法,此處可以借用歸并排序的思想來解決此題,此時時間復雜度為O(n*logn)。歸并排序,具體是先進行對半劃分,直到最后左半邊數組只有一個元素,右半邊數組中也只有一個元素時,此時開始進行回溯合并。那么,計算逆序對個數的關鍵,就在于此處的回溯合并過程,當左半邊元素(PS:回溯過程中,左半邊和右半邊元素均已是升序排序)中出現大于右半邊元素時,那么左半邊這個元素及其后面的所有元素均大于這個右半邊元素,記這些元素個數為len,那么逆序對個數要自增len

具體代碼如下:

package com.liuzhen.systemExe;public class Main{public long count = 0;   //全局變量,使用合并排序,計算逆序對數//使用歸并排序方法計算數組A中的逆序對數public void getReverseCount(int[] A) {if(A.length > 1) {int[] leftA = getHalfArray(A, 0);   //數組A的左半邊元素int[] rightA = getHalfArray(A, 1);  //數組A的右半邊元素
            getReverseCount(leftA);getReverseCount(rightA);mergeArray(A, leftA, rightA);}}//根據judge值判斷,獲取數組A的左半邊元素或者右半邊元素public int[] getHalfArray(int[] A, int judge) {int[] result;if(judge == 0) {   //返回數組A的左半邊result = new int[A.length / 2];for(int i = 0;i < A.length / 2;i++)result[i] = A[i];} else {    //返回數組的右半邊result= new int[A.length - A.length / 2];for(int i = 0;i < A.length - A.length / 2;i++)result[i] = A[A.length / 2 + i];}return result;}//合并數組A的左半邊和右半邊元素,并按照非降序序列排列public void mergeArray(int[] A, int[] leftA, int[] rightA) {int len = 0;int i = 0;int j = 0;int lenL = leftA.length;int lenR = rightA.length;while(i < lenL && j < lenR) {if(leftA[i] > rightA[j]) {A[len++] = rightA[j++]; //將rightA[j]放在leftA[i]元素之前,那么leftA[i]之后lenL - i個元素均大于rightA[j]count += (lenL - i);   //合并之前,leftA中元素是非降序排列,rightA中元素也是非降序排列。所以,此時就新增lenL - i個逆序對} else {A[len++] = leftA[i++];}}while(i < lenL)A[len++] = leftA[i++];while(j < lenR)A[len++] = rightA[j++];}//獲取一個隨機數數組public int[] getRandomArray(int n) {int[] result = new int[n];for(int i = 0;i < n;i++) {result[i] = (int)( Math.random() * 50);  //生成0~50之間的隨機數
        }return result;}public static void main(String[] args){long t1 = System.currentTimeMillis();Main test = new Main();int[] A = test.getRandomArray(50000);test.getReverseCount(A);long t2 = System.currentTimeMillis();System.out.println("分治法得到結果:"+test.count+", 耗時:"+(t2 - t1)+"毫秒");}
}

運行結果(運行3次):

分治法得到結果:612226489, 耗時:36毫秒分治法得到結果:610481152, 耗時:35毫秒分治法得到結果:612161208, 耗時:32毫秒

?

?

?

參考資料:

? ? ? 1.?歸并排序求逆序對

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541782.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541782.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c#copyto_String.CopyTo()方法以及C#中的示例

c#copytoC&#xff03;String.CopyTo()方法 (C# String.CopyTo() Method) String.CopyTo() method is used to copy a specified number of characters from given indexes of the string to the specified position in a character array. String.CopyTo()方法用于將指定數量的…

怎么查看我的php版本,怎樣查看php版本

怎樣查看php版本方法一&#xff1a;命令行查詢如果已經配置好環境變量&#xff0c;直接在命令行中輸入php -v&#xff0c;將會顯示php的版本信息。如果沒有配置環境變量&#xff0c;直接在命令行中進入到php的安裝目錄后&#xff0c;再輸入命令php -v&#xff0c;如圖所示是我在…

c ++ 繼承_C ++繼承| 查找輸出程序| 套裝1

c 繼承Program 1: 程序1&#xff1a; #include <iostream>#include <string.h>using namespace std;class Person {char name[15];int age;public:void SetPerson(int age, char* name){this->age age;strcpy(this->name, name);}};class Student : publi…

xor在PHP是什么意思,?=‘在PHP中是什么意思?

萬千封印因為它不會增加任何價值echo&#xff0c;我認為您希望了解PHP中的確切含義&#xff1a;Array([0] > Array([0] > 368 // T_OPEN_TAG_WITH_ECHO[1] > [2] > 1)[1] > Array([0] > 309 // T_VARIABLE[1] > $a [2] > 1)[2] > ; // U…

php curl keepalive,HTTPKeepAlive,開啟還是關閉

所謂「HTTP Keep-Alive」&#xff0c;在維基百科里稱為「HTTP Persistent Connection」&#xff0c;說白了就是復用HTTP連接&#xff0c;如此一來理論上客戶端的用戶體驗會更流暢&#xff0c;但是與之相對服務端不得不維持大量的連接。開啟還是關閉&#xff0c;這是個問題。一個…

如何使用ES6中的參數

ECMAScript 6&#xff08;或者叫 ECMAScript 2015&#xff09;是 ECMAScript 的最新標準&#xff0c;極大的提高了 JavaScript 中處理參數的能力。現在我們可以使用 rest 參數&#xff08;rest parameters&#xff09;、默認值&#xff08;default values&#xff09;和解構&am…

c++中tle是什么意思_如何在競爭性編程中克服TLE?

c中tle是什么意思什么是TLE&#xff1f; (What is TLE?) TLE means "Time Limit Exceed". So, in competitive programming, there are some constraints with a specific time limit (normally for each input 1 sec) and your task is to write your code in such…

美顏相機window 開源_X-Window系統| 免費和開源軟件

美顏相機window 開源X窗口系統 (The X-Window System) The X-Window System is a GUI that sits over Linux. Not at all like Microsoft Windows, the X Window System can glance and work in an enormously wide range of ways. It can work smoothly or lag, look excellen…

php 代碼 自動檢查工具下載,PHP_CodeSniffer安裝和使用教程(自動代碼檢查規范工具)...

在我們開發中都會講究代碼規范&#xff0c;若是個人開發者&#xff0c;代碼規范與否&#xff0c;只要自己看得懂便可以了&#xff0c;但是在團隊協作中&#xff0c;代碼規定尤為重要&#xff0c;下面&#xff0c;我們介紹一款PHP_CodeSniffer&#xff0c;自動檢查代碼規范的工具…

國際象棋之跳馬程序

問題描述: 假設國際象棋棋盤有5*5共25個格子。設計一個程序,使棋子從初始位置&#xff08;棋盤格編號為1的位置)開始跳馬,能夠把棋盤的格子全部走一遍,每個格子只允許走一次。要求: 1) 輸出一個解(用二維數組來記錄馬跳的過程,即[步號,棋盤格編號],左上角為第一步起點)&#xf…

kafka安裝使用

版本&#xff1a;kafka_2.11-0.10.1.0 (之前安裝2.10-0.10.0.0&#xff0c;一直出問題) 安裝Springboot結合Kafka的使用安裝 下載并解壓代碼 wget http://mirrors.cnnic.cn/apache/kafka/0.10.0.0/kafka_2.10-0.10.0.0.tgz #http://kafka.apache.org/downloadstar -zxvf kafka…

php獲取上傳文件路徑 fakepath,JavaScript_js獲取上傳文件的絕對路徑實現方法,在html中input type=file - phpStudy...

js獲取上傳文件的絕對路徑實現方法在html中function upload() {var filename document.getElementById("importFile").value;// 這時的filename不是 importFile 框中的值alert(filename);}如上面的代碼&#xff0c;用文件上傳對話框選擇文件后&#xff0c;如果選擇&…

在Bootstrap中使用類的按鈕類型

Bootstrap has 7 different types of buttons with contextual classes from which we can create buttons easily by using these classes (.btn-default, .btn-success, .btn-danger, .btn-primary, .btn-info, .btn-warning, .btn-link). Bootstrap具有上下文類型的 7種不同…

php json encode中文亂碼,php json_encode中文亂碼如何解決

php encode中文亂碼的解決辦法&#xff1a;首先打開相應的PHP文件&#xff1b;然后使用正則語句“preg_replace("#\\\u([0-9a-f]{4})#ie","iconv(UCS-2BE, UTF-8...)”將編碼替換成中文即可。本文列舉3個方法&#xff0c;實現json_encode()后的string顯示中文問…

鄉村圖景(轉載)

轉自: http://cul.qq.com/a/20160205/046437.htm 我丈夫家在湖北孝感孝昌縣的一個村子。2005年第一次過年回到他家&#xff0c;印象最深的就是嫂子。我暗自問當時的男友&#xff0c;“哥哥盡管算不上特別帥氣&#xff0c;但為何找了這么難看的嫂子&#xff1f;”后來才發現&…

stl向量最大值_C ++ STL中向量的最小和最大元素

stl向量最大值Given a vector and we have to find the smallest (minimum) and largest (maximum) elements. 給定一個向量&#xff0c;我們必須找到最小(最小)和最大(最大)元素。 查找向量的最小和最大元素 (Finding vectors minimum & maximum elements) To find minim…

oracle如何設置備份計劃任務,Oracle數據庫設置任務計劃備份一周的備份記錄

Oracle 數據庫備份&#xff1a;--保留最近一周的備份記錄&#xff1b;正文&#xff1a;開始代碼如下:echo 設置備份文件存放文件夾...set "tbufE:\Cway\backup"echo 設置備份文件名(以星期幾命名&#xff0c;即備份文件只保存最近一周)...set name%date%set name%nam…

索引(轉載自百度百科)

Oracle索引 編輯本詞條缺少信息欄、名片圖&#xff0c;補充相關內容使詞條更完整&#xff0c;還能快速升級&#xff0c;趕緊來編輯吧&#xff01;在oracle索引是一種供服務器在表中快速查找一個行的數據庫結構。合理使用索引能夠大大提高數據庫的運行效率。目錄 1 概念及作用 2…

阿姆斯特朗數_阿姆斯特朗的功能依賴公理 數據庫管理系統

阿姆斯特朗數Armstrong axioms are a complete set of inference rules or axioms, introduced and developed by William W. Armstrong in 1974. The inference rules are sound which is used to test logical inferences of functional dependencies. The axiom which also …

ORACLE JOB 失敗 查看,Oracle JOB異常中斷原因分析

注釋今天研發同事找我確認 PKG_WMS.proc_TaskMain 存儲的 job 是否還在運行&#xff0c;竟發現 dba_jobs.NEXT_DATE4000/1/1&#xff0c;如下看看究竟原因吧~JOB 信息&#xff1a;參數&#xff1a;BROKEN : 中斷標記 ,N 啟動、Y 中斷 --> DBMS_JOBS.BROKEN(job_id,TRUE/FA…