Java 演算法之求逆序對

2021-08-20 07:14:52 字數 1423 閱讀 5106

逆序對問題:

給定乙個陣列,如:[8, 8, 3, 0, 6, 8, 9, 3],前大後小的資料即為乙個逆序對,例如[8,3]、[3,0],求出這一陣列中的所有逆序對。

思路:暴力法:設定雙重迴圈,數量標誌,比較兩兩之間的大小,符合逆序對標準則數量標誌+1,複雜度o(n^2),本例中不考慮這個方法。

合併排序:合併排序是將乙個陣列均分,遞迴呼叫對子陣列進行排序,然後將子陣列合併,主要使用分治思想。在本題中,示例陣列可分為:

[8,8,3,0]

[6,8,9,3]

分別排序之後為 

a: [0,3,8,8]

b: [3,6,9,8] 

設定i=0,j=0分別標誌a、b陣列,在合併的過程中,比較a[i]、b[j],若a[i]>b[j] 則將b[i]放入原陣列,i++,同理將資料依次放入。 

解決逆序對的最關鍵的就是合併這一步,假設a[i]>b[i]了,那麼a[i]之後的所有資料,都是大於b[i]的,此時設定乙個標識,用於記錄資料,返回這個資料,遞迴,最後就可以得到所有逆序對了,這一方法的時間複雜度為o(nlogn),在陣列資料非常多的時候可以明顯感受到它的效率。

以下是它的實現**,其實就是在合併排序的基礎上,記錄一下逆序對個數:

public static void dectest(int a) 

private static int mergesort(int a)

int b = new int[n / 2];

system.arraycopy(a, 0, b, 0, n / 2);

int c;

if (n % 2 == 0) else

count += mergesort(b);

count += mergesort(c);

count += merge(b, c, a);

return count;

}private static int merge(int b, int c, int a) else

k++;

}if (i == p)

} else if (j == q)

}return count;

}public static void main(string args)

long t = system.currenttimemillis();

dectest(a);

system.out.print("耗時:");

system.out.println(system.currenttimemillis() - t);

}

本例中測試了百萬個資料,以下是執行結果:

百萬個資料119mm執行完畢,速度是十分可觀的。

合併演算法求逆序對

include include include include using namespace std define num 5 int number 0 void mergesort int a,int length void mergepart int a,int b,int l,int r v...

分治演算法 求逆序對

題目 給定乙個序列a1,a2,an,如果存在iaj,那麼我們稱之為逆序對,求逆序對的數目。解析 這道題 只要雙重迴圈就可以解決 但是因為題目要求 所以被迫使用更麻煩的方法 這道題其實就是歸併排序 至於為何 就不說了 歸併排序 就是將乙個陣列 不斷分割 一直分割到只剩乙個為止 乙個的話 必定是有序的 ...

演算法之逆序對

假設a 1.n 是乙個有n個不同數的陣列。若ia j 則對偶 i,j 稱為a的乙個逆序對 inversion 列出陣列的5個逆序對 由集合中的元素構成的什麼陣列具有最多的逆序對?它有多少逆序對?插入排序的執行時間與輸入陣列中的逆序對的數量有什麼關係?給出乙個求在n個元素的任何排列中逆序對數量的演算法...