復(fù)雜度分析(下)

+文本內(nèi)容是對王爭《數(shù)據(jù)結(jié)構(gòu)與算法之美》課程的筆記, 如果有任何侵權(quán)行為畔勤, 請聯(lián)系博主刪除

最好底燎、最壞時間復(fù)雜度

先給個例子:

// n 表示數(shù)組 array 的長度
int find(int[] array, int n, int x){
    int i = 0;
    int pos = -1;
    for(; i<n; ++i){
        if (array[i] == x){
            pos = i;
        }
    }
    return pos
}

按照上次的分析方法, 這段代碼的復(fù)雜度是O(n), 其中, n代表數(shù)組的長度.

但是在數(shù)組中查找一個數(shù)據(jù), 不需要從頭到尾遍歷一遍, 在中間可能就可以提前結(jié)束循環(huán). 優(yōu)化代碼.

// n 表示數(shù)組 array 的長度
int find(int[] array, int n, int x){
    int i = 0;
    int pos = -1;
    for(; i<n; ++i){
        if(array[i] == x){
            pos = i;
            break;
        }
    }
    return pos;
}

如果數(shù)組的第一個元素正好是要查找的變量x, 那時間復(fù)雜度是O(1). 但是如果數(shù)組中不存在變量x, 那時間復(fù)雜度是O(n).

由此引入三個概念: 最好情況時間復(fù)雜度熬芜、最壞情況時間復(fù)雜度和平均情況復(fù)雜度.

最好情況時間復(fù)雜度和最壞情況時間復(fù)雜度都很好理解, 重點記錄一下平均情況時間復(fù)雜度.

平均情況時間復(fù)雜度

查找變量x在數(shù)組中的位置, 有n+1種情況: 在數(shù)組的0 \sim n-1位置中和不在數(shù)組中. 把每種情況下, 需要遍歷的元素累加起來, 然后再除以n+1, 就可以得到需要遍歷的元素個數(shù)的平均值, 即:
\frac{1+2+3+\cdots+n-1+n}{n+1} = \frac{n(n+3)}{2(n+1)}
將其簡化后可得O(n). 但是, 這個結(jié)果是有問題的, 因為每種情況出現(xiàn)的概率不一樣.

要查找的變量x, 要么在數(shù)組里, 要么不在數(shù)組里. 為了方便理解, 假設(shè)在數(shù)組中與不在數(shù)組中的概率都為\frac{1}{2}. 另外, 要查找的數(shù)據(jù)出現(xiàn)在0 \sim n-1n個位置的概率也是一樣的, 為\frac{1}{n}. 所以, 根據(jù)概率乘法法則, 要查找的數(shù)據(jù)出現(xiàn)在0 \sim n-1中任意位置的概率就是\frac{1}{2n}.

計算過程為:
1 \times \frac{1}{2n}+2 \times \frac{1}{2n}+3\times\frac{1}{2n}+ \cdots +n \times \frac{1}{2n} + n \times \frac{1}{2} = \frac{3n+1}{4}
這個值就是概率論中的加權(quán)平均值, 也叫作期望值, 所以平均時間復(fù)雜度的全稱應(yīng)該叫加權(quán)平均時間復(fù)雜度或者期望時間復(fù)雜度.

這段代碼的加權(quán)平均時間復(fù)雜度仍然是O(n).

均攤時間復(fù)雜度

均攤時間復(fù)雜度, 聽起來跟平均時間復(fù)雜度有點兒像. 但是, 其應(yīng)用場景更加特殊、更加有限.

// array 表示一個長度為 n 的數(shù)組
// 代碼中的 array.length 就等于 n
int[] array = new int[n];
int count = 0;

void insert(int val){
    if(count == array.length){
        int sum = 0;
        for(int i=0; i<array.length; ++i){
            sum = sum + array[i];
        }
        array[0] = sum;
        count = 1;
    }
    array[count] = val;
    ++count;
}

最理想的情況是, 數(shù)組中有空閑空間, 我們只需要將數(shù)據(jù)插入到數(shù)組下表為count的位置就可以了, 所以最好情況時間復(fù)雜度為O(1). 最壞的情況下, 數(shù)組中沒有空閑空間了, 我們需要先做一次數(shù)組的遍歷求和, 然后再將數(shù)據(jù)插入, 所以最壞情況時間復(fù)雜度為O(n).

而平均時間復(fù)雜度是O(1). 我們還是可以通過概率論的方法來分析.

假設(shè)數(shù)組的長度是n, 根據(jù)數(shù)據(jù)插入的位置的不同, 我們可以分為n種情況, 每種情況的時間復(fù)雜度是O(1). 除此之外, 還有一種"額外"的情況, 就是在數(shù)組沒有空閑空間時插入一個數(shù)據(jù), 這個時候的時間復(fù)雜度是O(n). 而且, 這n+1種情況發(fā)生的概率一樣, 都是\frac{1}{n+1}. 所以, 根據(jù)加權(quán)平均的計算方法, 我們求得的平均時間復(fù)雜度就是:
1 \times \frac{1}{n+1}+1\times\frac{1}{n+1}+\cdots+1\times\frac{1}{n+1}+n\times\frac{1}{n+1} = O(1)
其實這個例子不需要引入概率論的知識, 對比一下insert()find()的例子, 就會發(fā)現(xiàn)這兩者有很大的差別.

首先, find()在極端情況下, 復(fù)雜度才為O(1). 但insert()在大部分情況下, 時間復(fù)雜度都為O(1). 只有個別情況下, 復(fù)雜度才為O(n). 這是insert()第一個區(qū)別與find()的地方.

第二個不同點, 對于insert()函數(shù)來說, O(1)時間復(fù)雜度的插入和O(n)時間復(fù)雜度的插入, 出現(xiàn)的頻率是非常有規(guī)律的, 而且有一定的前后時序關(guān)系, 一般都是一個O(n)插入之后, 緊跟著n-1O(1)的插入操作, 循環(huán)往復(fù).

針對這樣一種特殊場景的復(fù)雜度分析, 我們并不需要像之前那樣, 找出所有的輸入情況及相應(yīng)的發(fā)生概率, 然后計算加權(quán)平均值. 為此, 引入一種更加簡潔的分析方法: 攤還分析法, 通過攤還分析法得到的時間復(fù)雜度我們起了一個名字, 叫均攤時間復(fù)雜度.

針對上述例子, 每一次O(n)的插入操作, 都會跟著n-1O(1)的插入操作, 所以把耗時多的那次操作均攤到接下來的n-1次耗時少的操作上, 均攤下來, 這一組連續(xù)的操作的均攤時間復(fù)雜度就是O(1).

總結(jié)其應(yīng)用場景:

對一個數(shù)據(jù)結(jié)構(gòu)進行一組連續(xù)操作中, 大部分情況下時間復(fù)雜度都很低, 只有個別情況下時間復(fù)雜度比較高, 而且這些操作之間存在前后連貫的時序關(guān)系, 這個時候, 我們就可以將一組操作放在一塊兒分析, 看是否能將較高時間復(fù)雜度那次操作的耗時, 平攤到其他那些時間復(fù)雜度比較低的操作上. 而且, 能夠應(yīng)用均攤時間復(fù)雜度分析的場合, 一般均攤時間復(fù)雜度就等于最好情況時間復(fù)雜度.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翁授,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晾咪,更是在濱河造成了極大的恐慌收擦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谍倦,死亡現(xiàn)場離奇詭異塞赂,居然都是意外死亡,警方通過查閱死者的電腦和手機昼蛀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門宴猾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叼旋,你說我怎么就攤上這事仇哆。” “怎么了夫植?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵讹剔,是天一觀的道長。 經(jīng)常有香客問我偷崩,道長辟拷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任阐斜,我火速辦了婚禮衫冻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谒出。我一直安慰自己隅俘,他們只是感情好邻奠,可當(dāng)我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著为居,像睡著了一般碌宴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒙畴,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天贰镣,我揣著相機與錄音,去河邊找鬼膳凝。 笑死碑隆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蹬音。 我是一名探鬼主播上煤,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼著淆!你這毒婦竟也來了劫狠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤永部,失蹤者是張志新(化名)和其女友劉穎独泞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扬舒,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡阐肤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讲坎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孕惜。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晨炕,靈堂內(nèi)的尸體忽然破棺而出衫画,到底是詐尸還是另有隱情,我是刑警寧澤瓮栗,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布削罩,位于F島的核電站,受9級特大地震影響费奸,放射性物質(zhì)發(fā)生泄漏弥激。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一愿阐、第九天 我趴在偏房一處隱蔽的房頂上張望微服。 院中可真熱鬧,春花似錦缨历、人聲如沸以蕴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丛肮。三九已至赡磅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宝与,已是汗流浹背焚廊。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伴鳖,地道東北人节值。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像榜聂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嗓蘑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,926評論 2 361