題目:在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。
解題思路:沒掃瞄到乙個數字的時候,逐個比較該數字和它後面的數字的大小,如果後面的數字比它小,則這兩個數字就組成了乙個逆序對。假設陣列中含有n個數字。由於每個數字都要和o(n)個數字作比較,因此這個演算法的時間複雜度o(n^2).
更快的演算法
我們可以考慮比較兩個相鄰的數字,過程如下圖所示:
如圖(a)和圖(b)所示,我們先把陣列分解成兩個長度為2的子陣列,再把這兩個子陣列分別拆分成兩個長度為1的子陣列。接下來一邊合併相鄰的子陣列,一邊統計逆序對的數目。在第一對長度為1的子陣列、中7大於5,因此(7,5)組成乙個逆序對,同樣在第二對長度為1的子陣列、中也有逆序對(6,4)。由於我們已經統計了這兩對子陣列內部的逆序對,因此需要把這兩對子陣列排序,以免在以後的統計過程中再重複統計。
注:圖中省略了最後一步,即複製第二個子陣列最後剩餘的4到輔助陣列中.(a)p1指向的數字大於p2指向的數字,表明陣列中存在的逆序對。p2指向的數字是第二個子陣列的第二個數字,因此第二個子陣列中有兩個數字比7小。把逆序對數目加2,並把7複製到輔助陣列,向前移動p1和p3。(b)p1指向的數字小於p2指向的數字,沒有逆序對,把p2指向的數字複製到輔助陣列,並向前移動p2和p3。(c)p1指向的數字大於p2指向的數字,因此存在逆序對,由於p2指向的數字是第二個子陣列的第乙個數字,子陣列中只有乙個數字比5小,把逆序對數目加1,並把5複製到輔助陣列,向前移動p1和p3.
統計逆序對的規律:先把陣列分割成子陣列,先統計出子陣列內部的逆序對的數目,然後再統計出兩個相鄰子陣列之間的逆序對的數目。在統計逆序對的過程中,還需要對陣列進行排序。如果對排序演算法很熟悉,我們不難發現這個排序的過程實際上就是歸併排序。
兩個鍊錶的第乙個公共結點
題目:輸入兩個鍊錶,找出它們的第乙個公共結點。鍊錶結點定義如下:
這兩個鍊錶是單向鍊錶。如果兩個單向鍊錶有公共的結點,那麼這兩個鍊錶從某一結點開始,他們的m_pnext都指向同乙個結點。但由於是單向鍊錶的結點,每乙個結點只有乙個m_pnext,因此從第乙個公共結點開始,之後他們所有結點都是重合的,不可能再出現分叉。所以兩個有公共結點而部分重合的鍊錶,拓撲形狀看起來像乙個y,而不可能像x.如下圖所示:
分別把兩個鍊錶的結點放入兩個棧裡,這樣兩個鍊錶的尾結點就位與兩個棧的棧頂,接下來比較兩個棧頂的結點是否相同。如果相同,則把棧頂彈出接著比較下乙個棧頂,直到找到最後乙個相同的結點。
陣列中逆序對
題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 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...