日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

算法中的复杂度分析

發(fā)布時(shí)間:2025/1/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法中的复杂度分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

復(fù)雜度

前言

來(lái)復(fù)習(xí)下,算法體重經(jīng)常聊到的復(fù)雜度

算法中我們經(jīng)常會(huì)從兩個(gè)角度去考慮算法的優(yōu)劣,那就是【時(shí)間維度】和【空間維度】

時(shí)間復(fù)雜度

時(shí)間復(fù)雜度:就是執(zhí)行當(dāng)前算法消耗的時(shí)間。

當(dāng)然我們這里講的時(shí)間復(fù)雜度是個(gè)更加通用的描述,因?yàn)槲覀冎来a在不同中機(jī)器中執(zhí)行的時(shí)間是不同的,性能好的機(jī)器可能就用的時(shí)間更短。

所以我們這里的時(shí)間復(fù)雜度,用的是【大O符號(hào)表示法】,即T(n) = O(f(n))

如何理解呢?先來(lái)個(gè)栗子

func sum(n int) int {sum :=0i:=3for m:=0;m<n;m++ {sum+=n*i+1}return sum }

比如上面這段代碼,循環(huán)了n次,那么時(shí)間復(fù)雜度就是O(n),如何分析呢?

我們假定每行代碼執(zhí)行的時(shí)間是一個(gè)時(shí)間顆粒,那我們上面的例子,第2和3行一共兩個(gè)時(shí)間顆粒,4和5行就是2*n個(gè)時(shí)間顆粒,總共就是(2n+2)個(gè)時(shí)間顆粒。

當(dāng)然這樣算下來(lái)時(shí)間復(fù)雜度是T(n) = O(2n+2),大 O 時(shí)間復(fù)雜度實(shí)際上并不具體表示代碼真正的執(zhí)行時(shí)間,而是表示代碼執(zhí)行時(shí)間隨數(shù)據(jù)規(guī)模增長(zhǎng)的變化趨勢(shì),所以,也叫作漸進(jìn)時(shí)間復(fù)雜度(asymptotic time complexity),簡(jiǎn)稱(chēng)時(shí)間復(fù)雜度。

如果 n 很大時(shí),而公式中的低階、常量、系數(shù)三部分并不左右增長(zhǎng)趨勢(shì),所以都可以忽略。也就是2n中的2和常量2都可以忽略,所以時(shí)間復(fù)雜度就是T(n) = O(n)

常數(shù)階O(1)

無(wú)論代碼執(zhí)行了多少行,只要是沒(méi)有循環(huán)等復(fù)雜結(jié)構(gòu),那這個(gè)代碼的時(shí)間復(fù)雜度就都是O(1),如:

func sum(n int) int {sum :=0i:=3sum=sum*ireturn sum }

因?yàn)檫@段代碼中沒(méi)有一個(gè)系數(shù),會(huì)導(dǎo)致代碼的執(zhí)行時(shí)間隨系數(shù)的變化而變化,所以不管這個(gè)代碼有多少行,都可以時(shí)間復(fù)雜度是 O(1)

一般情況下,只要算法中不存在循環(huán)語(yǔ)句、遞歸語(yǔ)句,即使有成千上萬(wàn)行的代碼,其時(shí)間復(fù)雜度也是Ο(1)。

線性階O(n)

比如我們剛開(kāi)始的這個(gè)例子

func sum(n int) int {sum :=0i:=3for m:=0;m<n;m++ {sum+=n*i+1}return sum }

代碼中有個(gè) for 循環(huán),代碼的執(zhí)行時(shí)間會(huì)因?yàn)?n 的變化而變化,并且是線性增加或減少,所以這里用 O(n) 來(lái)表示他的時(shí)間復(fù)雜度。

對(duì)數(shù)階O(logN)

func sum(n int) int {sum :=0for sum<n {sum+=n*2}return sum }

這里同樣也是一個(gè)循環(huán),只不過(guò)每次都乘以2。也就是2的 x 次方大于等于 n 。 執(zhí)行的次數(shù)就是 x 。

接著上面轉(zhuǎn)換的結(jié)果,對(duì)于省略掉常數(shù)2,所以時(shí)間復(fù)雜度就是 O(logN)

實(shí)際上,不管是以2為底、以3為底,還是以10為底,我們可以把所有對(duì)數(shù)階的時(shí)間復(fù)雜度都記為 O(logn)

線性對(duì)數(shù)階O(nlogN)

將上面的代碼實(shí)例,外面在循環(huán) n 次,時(shí)間復(fù)雜度就是下面我們要討論的 O(nlogN)

func sum(n int) int {sum :=0for i:=0;i<n;i++{for sum<n {sum+=n*2}}return sum }

這個(gè)就不展開(kāi)討論了,內(nèi)層循環(huán)是上面我們討論的 O(logN) ,外面多了一層循環(huán),所以時(shí)間復(fù)雜度就是 O(nlogN)

平方階O(n2)

這個(gè)就很好理解了,就是兩層代碼的循環(huán)

func sum(m,n int) int {sum :=0for i:=0;i<m;i++{for j:=0;j<n;j++ {sum+=j}}return sum }

當(dāng)然有三層循環(huán)就是 O(n3),依次類(lèi)推

空間復(fù)雜度

空間復(fù)雜度全稱(chēng)就是漸進(jìn)空間復(fù)雜度(asymptotic space complexity),表示算法的存儲(chǔ)空間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系。

來(lái)個(gè)栗子分析下

func test(n int) map[int]struct{} {testMap := make(map[int]struct{}, n)for i := 0; i < n; i++ {testMap[i] = struct{}{}}return testMap }

比如上面的這段代碼,空間復(fù)雜度是 O(n)

我們可以看到 for 開(kāi)始的時(shí)候申請(qǐng)了一個(gè)變量 i ,這是常量級(jí)別的,跟數(shù)據(jù)規(guī)模 n 沒(méi)有關(guān)系,所以我們可以忽略。我們初始化了一個(gè)長(zhǎng)度為 n 的 testMap。testMap 的長(zhǎng)度會(huì)根據(jù) n 的變化而變化,所以這段代碼的空間復(fù)雜度就是 O(n)。

常數(shù)階O(1)

這個(gè)很簡(jiǎn)單

func sum(n int) int {sum :=0i:=3sum=sum*ireturn sum }

因?yàn)闆](méi)有變量跟隨數(shù)據(jù)規(guī)模 n 的變化而變化,所以空間復(fù)雜度就是 O(1)。

平方階O(n2)

看個(gè)栗子

func test(n int) [][]int {var sil = make([][]int, n)for i := 0; i < n; i++ {for j := 0; j < n; j++ {sil[i] = append(sil[i], j)}}return sil }

定義了二維切片,隨著兩層循環(huán),分別申請(qǐng)了 n*n 個(gè)空間的大小,所以空間復(fù)雜度就是 O(n2)

當(dāng)然有二維切片就是 O(n3),依次類(lèi)推

最好、最壞情況時(shí)間復(fù)雜度

最好情況時(shí)間復(fù)雜度就是,在最理想的情況下,執(zhí)行這段代碼的時(shí)間復(fù)雜度。

最壞情況時(shí)間復(fù)雜度就是,在最糟糕的情況下,執(zhí)行這段代碼的時(shí)間復(fù)雜度。

比如這段代碼

func sum(n, m int) int {sum := 0for i := 0; i < n; i++ {if sum == m {return sum}sum += i * 2}return sum }

如果在第一次循環(huán)的時(shí)候,sum == m?就結(jié)束程序,那么這個(gè)時(shí)候的時(shí)間復(fù)雜度就是最好時(shí)間復(fù)雜度。

當(dāng)然如果上面的 for 循環(huán),遍歷到最后一次也沒(méi)滿足?sum == m,那么這個(gè)時(shí)候的時(shí)間復(fù)雜度就是最壞情況時(shí)間復(fù)雜度。

平均情況復(fù)雜度

顧名思義就是,最好和最壞的時(shí)間復(fù)雜度的平均值。

比如上面的那個(gè)例子

引入概率之后,前面那段代碼的加權(quán)平均值為(3n+1)/4。用大O表示法來(lái)表示,去掉系數(shù)和常量,這段代碼的加權(quán)平均時(shí)間復(fù)雜度仍然是O(n)。

均攤時(shí)間復(fù)雜度

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

其實(shí)也可以認(rèn)為均攤時(shí)間復(fù)雜度就是一種特殊的平均時(shí)間復(fù)雜度。

總結(jié)

這里大概介紹了空間復(fù)雜度和時(shí)間復(fù)雜度

時(shí)間復(fù)雜度的全稱(chēng)是漸進(jìn)時(shí)間復(fù)雜度,表示算法的執(zhí)行時(shí)間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系。類(lèi)比一下,空間復(fù)雜度全稱(chēng)就是漸進(jìn)空間復(fù)雜度(asymptotic space complexity),表示算法的存儲(chǔ)空間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系。

這里的計(jì)算使用的是【大 O 復(fù)雜度表示法】,時(shí)間復(fù)雜度和空間復(fù)雜度只和數(shù)據(jù)規(guī)模 n 有關(guān)系,公式中的低階、常量、系數(shù)三部分不影響增加趨勢(shì),所以不收這三個(gè)的影響。

總結(jié)

以上是生活随笔為你收集整理的算法中的复杂度分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。