数据结构与算法--数组中的逆序对
-
題目:在數(shù)組中的兩個數(shù)字如果簽名一個數(shù)字大于后面的數(shù)組,則這兩個數(shù)字組成一個逆序對。輸入一個數(shù)組,求出這個數(shù)組中的逆序對的總數(shù)。
-
案例:輸入數(shù)組{7,5,6,4}中一共有5個逆序對分別是{7,6},{7,5},{7,4},{6,4},{5,4}
-
如上題描述,最簡單的方案就是雙循環(huán)遍歷整個數(shù)組,掃描第一個數(shù)字的時候讓他與其他數(shù)字逐個比較,記錄下比他小的數(shù)字并且累加一,這個類似冒泡排序的一個算法
-
雙循環(huán)的方案時間復雜度與冒泡排序是一樣的都是O(n2),應該有更快的方案
-
方案二:
- 還是用{7,5,6,4}作為案例分析,既然我們不能拿到第一個后與后面列表逐個比較,那么我們拆解開看能否得到更優(yōu)方案
- 我們將數(shù)組按從左到右拆解成一個元素一個元素的單個數(shù)組
- 接著一遍合并相鄰的子數(shù)組,一遍統(tǒng)計逆序對的數(shù)目
- 我們用如下圖解
-
第一步,我們將數(shù)組每次拆解一半,知道數(shù)組只剩下1 個或者2個,我們此處用最好理解的方案,拆解成獨立的一個
-
第二步,逐個比較相鄰的,7 < 5 是一個逆序對,我們應該count +1,并且將兩個獨立數(shù)組合并成一個有序數(shù)組,同理6與4 也是一樣,得到兩個數(shù)組,分別是{7,5}, {6,4}
-
第三部接著合并得到的兩個數(shù)組,并統(tǒng)計,如下圖中,當left指針指向7 ,right指向6 此時left > right,
-
因為此時兩個數(shù)組都是順序的,那么left指向的數(shù)據(jù)比 第二個數(shù)組中所有數(shù)都要大
-
那么count疊加次數(shù)應該是第二個數(shù)組的長度,或者說是right指向的數(shù)據(jù)的下標大小+1
-
接著移動left,right,并且將較大的數(shù)放入合并的數(shù)組中
-
如上步驟和我們先進行拆解,然后對子數(shù)組逐個進行統(tǒng)計排序的方式和我們之前 文章:數(shù)據(jù)結構與算法–排序算法總結(動圖演示) 講到的歸并排序的思想是一樣的
-
只不過我們之前的實現(xiàn)中歸并排序拆解的時候選擇的是拆解成2 個,因為這樣可減少遞歸的次數(shù)
-
此時我們選擇拆解成1個,是因為我們目的是需要統(tǒng)計次數(shù),如果拆解成2個,必須在對這兩個進行單獨排序的時候單獨統(tǒng)計,這樣多了多余的邏輯
-
經如上分析有如下代碼:
- 如上算法中與歸并算法一樣時間復雜度是O(nlogn),比最直觀的方案一O(n2)要快,但是我們需要額外一個長度為n的數(shù)組,空間復雜度是O(n),我們用空間換時間的算法。
上一篇:數(shù)據(jù)結構與算法–第一個只出現(xiàn)一次的字符
下一篇:數(shù)據(jù)結構與算法–兩個鏈表中第一個公共節(jié)點
總結
以上是生活随笔為你收集整理的数据结构与算法--数组中的逆序对的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法--第一个只出现一次的字符
- 下一篇: 数据结构与算法--两个链表中第一个公共节