算法練習 逆序對
逆序對問題算是很經典了,最簡單的暴力破解時間複雜度O(n2),時間複雜度大於O(n2)的算法是非常糟糕了,所以我們採用歸併排序的算法改動一下,即可獲得O(nlogn)的算法。
逆序對定義:數列中如果 i < j && arr[i] > arr[j],則arr[i]和arr[j]爲一對逆序對。
- java算法參考
// 逆序對個數
private static long ropCount = 0;
/**
* 計算逆序對
*
* @param arr
* @param left
* @param right
*/
public static void calcRop(int[] arr, int left, int right) {
if (left >= right)
return;
int mid = (left + right) >>> 1;
calcRop(arr, left, mid);
calcRop(arr, mid + 1, right);
calc(arr, left, mid, right);
}
/**
* 一次計算
*
* @param arr
* @param left
* @param mid
* @param right
*/
public static void calc(int[] arr, int left, int mid, int right) {
int i = left;
int j = mid + 1;
while (i < j && j <= right) {
while (i < j && arr[i] <= arr[j])
i++;
ropCount += j - i;
int temp = arr[j];
System.arraycopy(arr, i, arr, i + 1, j - i);
arr[i] = temp;
i++;
j++;
}
}
- 算法測試
正確性測試
有那麼幾組數據
數據 | 逆序對的數量 |
---|---|
{ 9, 8, 7, 5, 2, 4, 5, 6 } | 20 |
{ 7, 5, 5, 4, 3, 3, 5, 4, 4, 1, 6 } | 32 |
{ 9, 8, 7, 1, 2, 3, 4, 3, 2, 1 } | 33 |
{ 7, 5 } | 1 |
{ 5, 5 } | 0 |
{ 5 } | 0 |
{ } | 0 |
分別跑起來,結果都對的上,暫未發現結果不符的數據。
壓力測試
跑一百萬條數據,看看用時。
int[] arr = new int[1000*1000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100 + 1);
}
long start = System.currentTimeMillis();
calcRop(arr, 0, arr.length - 1);
System.out.println(ropCount);
long end = System.currentTimeMillis();
System.out.println("一百萬條數據用時:" + (end-start)/1000 + "s");
害!可能是我自己寫的一次歸併算法不好,一百萬條數據竟然要用一分鐘。。。
先這麼着吧!拜了個拜!