劍指offer----數(shù)組中的逆序對

題目:在數(shù)組中的兩個數(shù)字砰粹,如果前面一個數(shù)字大于后面的數(shù)字唧躲,則這兩個數(shù)字組成一個逆序對。輸入一個數(shù)組,求出這個數(shù)組中的逆序對的總數(shù)P碱璃。并將P對1000000007取模的結果輸出弄痹。 即輸出P%1000000007
輸入描述:
題目保證輸入的數(shù)組中沒有的相同的數(shù)字

數(shù)據(jù)范圍:

對于%50的數(shù)據(jù),size<=10^4

對于%75的數(shù)據(jù),size<=10^5

對于%100的數(shù)據(jù),size<=2*10^5

示例1
輸入
1,2,3,4,5,6,7,0
輸出
7

public class Solution {
    public int InversePairs(int [] array) {
        if(array == null || array.length == 0){
            return 0;
        }
        int[] copy = new int[array.length];
        for(int i = 0; i < array.length; i++){
            copy[i] = array[i];
        }
        int count = helper(array, copy, 0, array.length - 1);
        return count;
    }
    int helper(int[] array, int[] copy, int low, int high){
        if(low == high){
            return 0;
        }
        int mid = (low + high) >> 1;
        int leftCount = helper(array, copy, low, mid) % 1000000007;
        int rightCount = helper(array, copy,mid + 1, high) % 1000000007;
        int count = 0;
        int i = mid;
        int j = high;
        int locCopy  = high;
        while(i >= low && j > mid){
            if(array[i] > array[j]){
                count += j - mid;
                copy[locCopy--] = array[i--];
                if(count >= 1000000007){
                    count%=1000000007;
                }
            }
            else{
                    copy[locCopy--] = array[j--];
            }
        }
        for(; i>=low;i--){
            copy[locCopy--] = array[i];
        }
        for(;j>mid;j--){
            copy[locCopy--]=array[j];
        }
        for(int s = low; s<=high;s++){
            array[s] = copy[s];
        }
        return (leftCount +rightCount + count) % 1000000007;
    }
}

牛客里有一個很好的回答

鏈接:https://www.nowcoder.net/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5
來源:徘镀鳎客網(wǎng)

思路分析:

看到這個題目肛真,我們的第一反應是順序掃描整個數(shù)組。沒掃描到一個數(shù)組的時候爽航,逐個比較該數(shù)字和它后面的數(shù)字的大小蚓让。如果后面的數(shù)字比它小乾忱,則這兩個數(shù)字就組成了一個逆序對。假設數(shù)組中含有n個數(shù)字历极。由于每個數(shù)字都要和O(n)這個數(shù)字比較窄瘟,因此這個算法的時間復雜度為O(n^2)。

我們以數(shù)組{7,5,6,4}為例來分析統(tǒng)計逆序對的過程执解。每次掃描到一個數(shù)字的時候寞肖,我們不拿ta和后面的每一個數(shù)字作比較,否則時間復雜度就是O(n^2)衰腌,因此我們可以考慮先比較兩個相鄰的數(shù)字。

image

(a) 把長度為4的數(shù)組分解成兩個長度為2的子數(shù)組觅赊;

(b) 把長度為2的數(shù)組分解成兩個成都為1的子數(shù)組右蕊;

(c) 把長度為1的子數(shù)組 合并、排序并統(tǒng)計逆序對 吮螺;

(d) 把長度為2的子數(shù)組合并饶囚、排序,并統(tǒng)計逆序對鸠补;

在上圖(a)和(b)中萝风,我們先把數(shù)組分解成兩個長度為2的子數(shù)組,再把這兩個子數(shù)組分別拆成兩個長度為1的子數(shù)組紫岩。接下來一邊合并相鄰的子數(shù)組规惰,一邊統(tǒng)計逆序對的數(shù)目。在第一對長度為1的子數(shù)組{7}泉蝌、{5}中7大于5歇万,因此(7,5)組成一個逆序對。同樣在第二對長度為1的子數(shù)組{6}勋陪、{4}中也有逆序對(6,4)贪磺。由于我們已經(jīng)統(tǒng)計了這兩對子數(shù)組內(nèi)部的逆序對,因此需要把這兩對子數(shù)組 排序 如上圖(c)所示诅愚, 以免在以后的統(tǒng)計過程中再重復統(tǒng)計寒锚。

接下來我們統(tǒng)計兩個長度為2的子數(shù)組子數(shù)組之間的逆序對。合并子數(shù)組并統(tǒng)計逆序對的過程如下圖如下圖所示违孝。

我們先用兩個指針分別指向兩個子數(shù)組的末尾刹前,并每次比較兩個指針指向的數(shù)字。如果第一個子數(shù)組中的數(shù)字大于第二個數(shù)組中的數(shù)字等浊,則構成逆序對腮郊,并且逆序對的數(shù)目等于第二個子數(shù)組中剩余數(shù)字的個數(shù),如下圖(a)和(c)所示筹燕。如果第一個數(shù)組的數(shù)字小于或等于第二個數(shù)組中的數(shù)字轧飞,則不構成逆序對衅鹿,如圖b所示。每一次比較的時候过咬,我們都把較大的數(shù)字從后面往前復制到一個輔助數(shù)組中大渤,確保 輔助數(shù)組(記為copy) 中的數(shù)字是遞增排序的。在把較大的數(shù)字復制到輔助數(shù)組之后掸绞,把對應的指針向前移動一位泵三,接下來進行下一輪比較。

image.png

過程:先把數(shù)組分割成子數(shù)組衔掸,先統(tǒng)計出子數(shù)組內(nèi)部的逆序對的數(shù)目烫幕,然后再統(tǒng)計出兩個相鄰子數(shù)組之間的逆序對的數(shù)目。在統(tǒng)計逆序對的過程中敞映,還需要對數(shù)組進行排序较曼。如果對排序算法很熟悉,我們不難發(fā)現(xiàn)這個過程實際上就是歸并排序振愿。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捷犹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子冕末,更是在濱河造成了極大的恐慌萍歉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件档桃,死亡現(xiàn)場離奇詭異枪孩,居然都是意外死亡,警方通過查閱死者的電腦和手機胳蛮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門销凑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仅炊,你說我怎么就攤上這事斗幼。” “怎么了抚垄?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵蜕窿,是天一觀的道長。 經(jīng)常有香客問我呆馁,道長桐经,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任浙滤,我火速辦了婚禮阴挣,結果婚禮上,老公的妹妹穿的比我還像新娘纺腊。我一直安慰自己畔咧,他們只是感情好茎芭,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著誓沸,像睡著了一般梅桩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拜隧,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天宿百,我揣著相機與錄音,去河邊找鬼洪添。 笑死垦页,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的干奢。 我是一名探鬼主播外臂,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼律胀!你這毒婦竟也來了?” 一聲冷哼從身側響起貌矿,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤炭菌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后逛漫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黑低,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年酌毡,在試婚紗的時候發(fā)現(xiàn)自己被綠了克握。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡枷踏,死狀恐怖菩暗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旭蠕,我是刑警寧澤停团,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站掏熬,受9級特大地震影響佑稠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜旗芬,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一舌胶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疮丛,春花似錦幔嫂、人聲如沸辆它。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娩井。三九已至,卻和暖如春似袁,著一層夾襖步出監(jiān)牢的瞬間洞辣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工昙衅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扬霜,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓而涉,卻偏偏與公主長得像著瓶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子啼县,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 數(shù)組 記錄《劍指offer》中所有關于數(shù)組的題目材原,以及LeetCode中的相似題目 相關題目列表 說明 由于簡書...
    wenmingxing閱讀 1,517評論 1 12
  • 數(shù)組系列文章也到尾聲了,這是數(shù)組系列的最后一篇文章季眷,后面就是樹的內(nèi)容了余蟹,如果后面又看到了相關的題目再作補充吧,歡迎...
    zero_sr閱讀 465評論 0 2
  • 秋天子刮,是一個既讓人喜悅又讓人悲哀的季節(jié)威酒。喜的是,一年的勞動沒有白費挺峡,得到了豐收葵孤;哀的是,落葉紛飛橱赠,沒有了生機勃...
    之言之語閱讀 722評論 2 5
  • 背井離鄉(xiāng)的婆婆尤仍,猶如留守在家的兒童一般,時常露出讓人心疼的孤獨神色病线。 生了孩子之后吓著,婆媳關系就是一個繞不開話題。而...
    韓燁hy閱讀 1,051評論 7 8
  • 城市街頭的共享單車百家爭鳴送挑,一方面給人們?nèi)粘3鲂袔矸奖惆筝海硪环矫嬖趩诬囀褂蒙弦蔡峁┙o用戶更多的選擇機會。但從用戶...
    諾斯漫底閱讀 210評論 0 0