題目描述
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。例如:
例如,有乙個陣列為array[0..n] 其中有元素a[i],a[j].如果 當i< j時,a[i]>a[j],那麼我們就稱(a[i],a[j])為乙個逆序對。在陣列中一共存在5對逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)。解題思路
看到這樣的題目,最簡單的想法就是遍歷每乙個元素,讓其與後面的元素對比,如果大於則count++
,但是這樣的時間複雜度是o(n2)
。這題有更好的解決方法,時間複雜度只需要o(nlogn)
。其實這道題目的思路跟歸併排序差不多,求逆序對的過程就是乙個求歸併排序的過程,在求出逆序對以後,原陣列變得有序,是通過歸併排序得到的。
總體的意思就是將陣列分成兩段,首先求段內的逆序對數量,比如下面兩段**就是求左右兩端陣列段內的逆序對數量
inversions+=inversepairscore(arry,start,mid,temp);//找左半段的逆序對數目
inversions+=inversepairscore(arry,mid+1,end,temp);//找右半段的逆序對數目
然後求段間的逆序對數量,如下面的**
inversions+=mergearray(arry,start,mid,end,temp);//在找完左右半段逆序對以後兩段陣列有序,然後找兩段之間的逆序對。最小的逆序段只有乙個元素。
然後在求段間逆序對的時候,我們分為arry[start…mid]和arry[mid+1…end],然後設定兩個指標ij分別指向兩段陣列的末尾元素,也就是i=mid,j=end。然後比較arry[i]和arry[j]:
仿造歸併排序演算法:
package com.genge.offer;
/** * created by genge on 2016-06-30.
*/public
class
inversepairs
//分治
private
intinversepairscore(int array, int start, int end, int temp)
return count;
}//合併
// 將有二個有序數列a[first...mid]和a[mid...last]合併。
private
intmergearray(int array,int start,int mid,int end,int temp)else
}while(i <= m )
while (j <= n)
system.arraycopy(temp, 0, array, start, k);//排序結果複製到源陣列,用for迴圈也行
return count;
}}
劍指offer 陣列中的逆序對
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。解法一 乙個數字能不能構成逆序對,關鍵看後面有幾個比他小的數字。根據這個思路,我們可以從後向前遍歷整個陣列。並用乙個大小為10的陣列,分別來儲存從後向前遍歷陣列時0 9每個數字...
劍指offer 陣列中的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。class solution vector tmp len int res mergesort data,tmp,0,len 1 return res private...
劍指offer 陣列中的逆序對
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。分析 類似於mergesort的思想,對於兩個排序的陣列,用兩個指標分別指向末尾,比如p,q,如果p的值大於q,那麼p與q和q之前所有數字都可以組成逆序對,count就加上後乙...