劍指offer 陣列中的逆序對

2021-07-14 05:47:30 字數 1616 閱讀 4535

題目描述

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

例如:

例如,有乙個陣列為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就加上後乙...