劍指Offer 第36題 陣列中的逆序對 java

2021-09-11 21:30:19 字數 2620 閱讀 9926

題目:在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數

例如在陣列{7,5,6,4}中,一共存在5對逆序對,分別是{7,6},{7,5},{7,4},{6,4},{5,4}。

看 到這個題目,我們的第一反應就是順序掃瞄整個陣列。每掃瞄到乙個陣列的時候,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這兩個數字就組成乙個逆序對。假設陣列中含有n個數字。由於每個數字都要和o(n)個數字做比較,因此這個演算法的時間複雜度為o(n2)。我們嘗試找找更快的演算法。

我們以陣列{7,5,6,4}為例來分析統計逆序對的過程,每次掃瞄到乙個數字的時候,我們不能拿它和後面的每乙個數字做比較,否則時間複雜度就是o(n2)因此我們可以考慮先比較兩個相鄰的數字。

如下圖所示,我們先把陣列分解稱兩個長度為2的子陣列,再把這兩個子陣列分別茶城兩個長度為1的子陣列。接下來一邊合併相鄰的子陣列,一邊統計逆序對的數目。在第一對長度為1的子陣列{7},{5}中7大於5,因此{7,5}組成乙個逆序對。同樣在第二對長度為1的子陣列{6},{4}中也有逆序對{6,4}。由於我們已經統計了這兩隊子陣列內部逆序對,因此需要把這兩對子陣列排序,以免在以後的統計過程中再重複統計。

接下來我們統計兩個長度為2的子陣列之間的逆序對。

我們先用兩個指標分別指向兩個子陣列的末尾,並每次比較兩個指標指向的數字。如果第乙個子陣列中的數字大於第二個子陣列中的數字,則構成逆序對,並且逆序對的數目等於第二個子陣列中的剩餘數字的個數。如果第乙個陣列中的數字小於或等於第二個陣列中的數字,則不構成逆序對。每一次比較的時候,我們都把較大的數字從後往前複製到乙個輔助陣列中去,確保輔助陣列中的數字是遞增排序的。在把較大的數字複製到陣列之後,把對應的指標向前移動一位,接著來進行下一輪的比較。

經過前面詳細的討論,我們可以總結出統計逆序對的過程:先把陣列分隔成子陣列,先統計出子陣列內部的逆序對的數目,然後再統計出兩個相鄰子陣列之間的逆序對的數目。在統計逆序對的過程中,還需要對陣列進行排序。如果對排序演算法很熟悉,我們不難發現這個排序的過程就是歸併排序。

**:

public class offer36 

int copy = new int[array.length];

for(int i = 0;i>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)else

copy[index--] = array[j--];

} for(;i>=start;i--)

copy[index--] = array[i];

for(;j>=mid+1;j--)

copy[index--] = array[j];

return count+leftcount+rightcount;

} public static void main(string args) ;

system.out.println(inversepairs(array1));

//功能測試,2,輸入遞增排序的陣列

int array2 =;

system.out.println(inversepairs(array2));

//功能測試,3,輸入遞減排序的陣列

int array3 =;

system.out.println(inversepairs(array3));

//功能測試,4,輸入的陣列中有重複數字

int array4 =;

system.out.println(inversepairs(array4));

//邊界值測試,5,輸入的陣列中只有兩個數字

int array5 =;

system.out.println(inversepairs(array5));

//邊界值測試,6,輸入的陣列中只有兩個數字

int array6 =;

system.out.println(inversepairs(array6));

//特殊輸入測試,表示陣列的指標為null

int array7 =null;

system.out.println(inversepairs(array7));

}}

執行結果:

506

4100

劍指Offer第36題 Java版

本題使用歸併排序的思想,結合歸併排序,寫出的演算法解。陣列中的逆序對 public static int inversepairs int array public static int mergecount int array,int copy,int start,int end int mid ...

劍指offer第50題 陣列中重複的數字

原始碼在乙個長度為n的陣列裡的所有數字都在0到n 1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字2。class solution return false boo...

劍指offer第35題 陣列中的逆序對

題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字 資料範圍 對於 50的資料,size 1...