求陣列中的逆序對 分治法
題目分析:先求前面一半陣列的逆序數,再求後面一半陣列的逆序數,然後求前面一半陣列比後面一半陣列中大的數的個數(也就是逆序數),這三個過程加起來就是整體的逆序數目了。這類似與歸併排序,歸併排序的思想就是把前一段排序,後一段排序,然後再整體排序。而且,歸併排序的規程中,需要判斷前一半陣列和後一半陣列中當前數字的大小。這也就是剛剛描述的逆序的判斷過程了。如果前一半陣列的當前數字大於後一半陣列的當前數字,那麼這就是一個逆序數。利用歸併排序的過程中,在每一次歸併兩個陣列的時候,如果左陣列比右陣列大,那麼著就是一個逆序。記錄所有左陣列比右陣列大的情況,就是全部的逆序數目。
具體解析:
圖片來自於兼職
先把陣列分解成兩個長度為2的子陣列,再把這兩個子陣列分解成兩個長度為1的子陣列。接下來一邊合併相鄰的子陣列,一邊統計逆序對的數目。在第一對長度為1的子陣列{7}、{5}中7>5,因此(7,5)組成一個逆序對。同樣在第二對長度為1的子陣列{6},{4}中也有逆序對(6,4),由於已經統計了這兩對子陣列內部的逆序對,因此需要把這兩對子陣列進行排序,避免在之後的統計過程中重複統計。
逆序對的總數=左邊陣列中的逆序對的數量+右邊陣列中逆序對的數量+左右結合成新的順序陣列時中出現的逆序對的數量;
//陣列中的逆序對
public static int InversePairs(int[] array){
if(array==null||array.length<=1)
return 0;
int[] copy = new int[array.length];
for(int i=0;i<array.length;i++){
copy[i] = array[i];
}
return mergeCount(array, copy, 0, array.length-1);
}
public static int mergeCount(int[] array, int[] copy, int start, int end){
if(start==end){
copy[start] = array[start];
return 0;
}
int mid = (start+end)>>1;
int leftCount = mergeCount(copy, array, start, mid);
int rightCount = mergeCount(copy, array, mid+1, end);
int i = mid;//i初始化為前半段最後一個數字的下標
int j = end;//j初始化為後半段最後一個數字的下標
int index = end;//輔助陣列複製的陣列的最後一個數字的下標
int count = 0;//計數--逆序對的數目
while(i>=start&&j>=mid+1){
if(array[i]>array[j]){
copy[index--] = array[i--];
count += j-mid;
}else{
copy[index--] = array[j--];
}
}
for(;i>=start;i--){
copy[index--] = array[i];
}
for(;j>=mid+1;j--){
copy[index--] = array[j];
}
return leftCount+rightCount+count;
}
相關推薦
求陣列中的逆序對 分治法
題目分析:先求前面一半陣列的逆序數,再求後面一半陣列的逆序數,然後求前面一半陣列比後面一半陣列中大的數的個數(也就是逆序數),這三個過程加起來就是整體的逆序數目了。這類似與歸併排序,歸併排序的思想就是把前一段排序,後一段排序,然後再整體排序。而且,歸併排序的規程中,需要判
(逆序對 分治法)P1908 逆序對 洛谷
style 說明 scan using lis region namespace 一個 bsp 題目描述 貓貓TOM和小老鼠JERRY最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,TOM老貓查閱到一個人類稱之為&ldq
演算法導論習題---求n個元素任何排列中逆序對的數量
問題描述: 設A[1…n]是一個包含n個不同數的陣列。如果在i < j的情況下,有A[i] > A[j],則(i,j)就稱為A中的一個逆序對(inversion),(逆序對的元素是下標,而不是數組裡的值)。給出一個演算法,它能用Θ(nlgn)的最壞
Codeforces Round #510 (Div. 2) A 模擬 B列舉 C D離散化+樹狀陣列(逆序對)
A Code: #include <bits/stdc++.h> #define LL long long #define INF 0x3f3f3f3f using namespace s
(演算法導論習題解problem2.4)尋找一個序列中逆序對的數量
#include <stdio.h>void display(int array[], int size){ int i; for (i =0; i < size; ++i) { printf("%d ", array[i]); } printf(
陣列中逆序的對數
class Solution { public: int InversePairs(vector<int> data) { if(data.size()<=1){ return 0;
樹狀陣列和逆序對
## 逆序對的概念 在一個有 $n$ 個元素的陣列 $A$ 中,如果存在 $1 \leqslant i A_j$ ,則稱 $$ 為 $A$ 的一個逆序對。我們熟知的排序其實就是一個消滅逆序對的過程。求一個數組的逆序對數目,我們可以用歸併排序,或者用我們今天的主角樹狀陣列,還不會樹狀陣
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。
/* 最簡單的思路:陣列的所有數兩兩比較,進行累加,空間複雜度為O(n^2) */ class Solution { public: int InversePairs(vector<int> data) { int P
POJ 2299 分治法求數列逆序對(歸併排序)
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 50482 Accepted: 18516 Description In this proble
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%100000000
分析:可以利用兩層for迴圈,從頭開始遍歷查詢每一個元素的逆序對數,然後求總和。也可以利用歸併排序的思想來求解。下面是利用歸併排序的思想求解 public class Solution{public int InversePairs(int[] array) {if (ar
離散化及樹狀陣列求逆序對
用樹狀陣列求逆序對的時候注意:要統計b[i]-1的字首和,因為可能有相同值的元素 不去重離散化: sort(a+1, a+n+1, cmp); for(int i=1; i<=n; i++) { if(i == 1 || a[i].val != a[i-1].val) { to
牛客網——陣列中的逆序對
很久沒玩過oj,今天刷了幾道題,感覺好吃力。果然刀還是要磨磨才鋒利 題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。 輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007
劍指offer:(36)時間效率和空間效率的平衡 :陣列中的逆序對
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 package cn.com.jianzhioffer; public class S
分治法求陣列中最大元素
原創 在陣列A[n]中,設m是其中最大元素,則m=max(A[0],max( A[1]……A[n-1]); 同理 max( A[1]……A[n-1] ) = max ( A[1] , max( A[2]……A[n-1] ); 設函式findMax( int index ) 是尋找陣列中最大
劍指offer系列(十三)陣列中的逆序對,兩個連結串列的第一個公共結點,數字在排序陣列中出現的次數
陣列中的逆序對 題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 輸入描述: 題目保證輸入的陣列中沒有的相同的數字
樹狀陣列求逆序對【TSOJ 1232】
傳送門就不傳送了,你們也傳送不進來; 就是一個求逆序對的裸題; 直接離散化+樹狀陣列就完事了。 樹狀陣列區間更新和區間查詢寫 這題總是不對; 我也不知道為啥,過幾天再研究吧。 單點更新的樹狀陣列寫對了; 總之就是如果用樹狀陣列的話一定要離散化。 下面是程式碼: #in
《劍指offer》系列 陣列中的逆序對(Java)
連結 牛客:陣列中的逆序對 題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 輸入描述 題目保證輸入的陣
poj2299樹狀陣列入門,求逆序對
今天入門了樹狀陣列 習題連結 https://blog.csdn.net/liuqiyao_01/article/details/26963913 離散化資料:用一個數組來記錄每個值在數列中的排名,不能用map,會超時 開結構體儲存每個數在數列中原來的位置,排序後用a陣列求出原來狀態下
(劍指offer)陣列中的逆序對
時間限制:2秒 空間限制:32768K 熱度指數:228207 本題知識點: 陣列 題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000
【劍指offer】陣列中的逆序對(校正書上錯誤)【歸併排序】
題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 題目保證輸入的陣列中沒有的相同的數字 資料範圍: