題目要求:
如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對總數。例如輸入,一共有5個逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)。
解題思路:
思路1:暴力解決。順序掃瞄陣列,對於每個元素,與它後面的數字進行比較,因此這種思路的時間複雜度為o(n^2)。
思路2:
上述思路在進行比較後,並沒有將相關資訊留下,其實在比較之後可以進行區域性的排序,從而降低比較的次數,降低時間複雜度。
可通過如下步驟求逆序對個數:先把陣列逐步分隔成長度為1的子陣列,統計出子陣列內部的逆序對個數,然後再將相鄰兩個子陣列合併成乙個有序陣列並統計陣列之間的逆序對數目,直至合併成乙個大的陣列。其實,這是二路歸併的步驟,只不過在歸併的同事要多進行一步統計。因此時間複雜度o(nlogn),空間複雜度o(n),如果使用原地歸併排序,可以將空間複雜度降為o(1)。
本文使用經典二路歸併排序實現。以為例,過程如下:
[7 5 6 4]
/ \ 分:將長度為4的陣列分成長度為2的陣列
[7 5] [6 4]
/ \ / \ 分:將長度為2的陣列分成長度為1的陣列
[7] [5] [6] [4]
\ / \ / 和:1->2,並記錄子陣列內的逆序對
[5 7] [4 6]
\ / 和:2->4,並記錄子陣列內的逆序對
[4 5 6 7]
**實現
package chapter5;
/** * created with intellij idea
* author: ryder
* date : 2017/8/14
* time : 19:36
* description:陣列中的逆序對
**/public class p249_inversepairs
public static int mergesortcore(int data,int start,int end)
//start~mid, mid+1~end
public static int mergersortmerge(int data,int start,int mid,int end)
}while (left<=mid-start)
data[index++] = temp[left++];
while (right<=end-start)
data[index++] = temp[right++];
return count;
}public static void main(string args)));
system.out.println(inversepairs(new int));
}}
執行結果
5
16
陣列中逆序對
題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...
陣列中的逆序對
來自劍指offer 分析 我們第一反應是順序掃瞄整個陣列,每掃瞄到乙個數字時,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這個兩個數字就組成了乙個逆序對。假設陣列有n個數字,由於每個數字都要和o n 個數字作比較,因此這個演算法的時間複雜度為o n 2 換思路 我們採用歸併思想,先考...
陣列中的逆序對
題目 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。用歸併排序演算法,歸併的時候,從後向前歸併。include using namespace std int getreversenum int p1,int p2,int...