RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深度剖析時(shí)間復(fù)雜度

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:代碼隨想錄 ? 作者:代碼隨想錄 ? 2022-03-18 10:18 ? 次閱讀

相信每一位錄友都接觸過(guò)時(shí)間復(fù)雜度,但又對(duì)時(shí)間復(fù)雜度的認(rèn)識(shí)處于一種朦朧的狀態(tài),所以是時(shí)候?qū)r(shí)間復(fù)雜度來(lái)一個(gè)深度的剖析了。

本篇從如下六點(diǎn)進(jìn)行分析:

  • 究竟什么是時(shí)間復(fù)雜度
  • 什么是大O
  • 不同數(shù)據(jù)規(guī)模的差異
  • 復(fù)雜表達(dá)式的化簡(jiǎn)
  • O(logn)中的log是以什么為底?
  • 舉一個(gè)例子

這可能是你見(jiàn)過(guò)對(duì)時(shí)間復(fù)雜度分析最通透的一篇文章。

究竟什么是時(shí)間復(fù)雜度

時(shí)間復(fù)雜度是一個(gè)函數(shù),它定性描述該算法的運(yùn)行時(shí)間。

我們?cè)谲浖_(kāi)發(fā)中,時(shí)間復(fù)雜度就是用來(lái)方便開(kāi)發(fā)者估算出程序運(yùn)行的答題時(shí)間。

那么該如何估計(jì)程序運(yùn)行時(shí)間呢,通常會(huì)估算算法的操作單元數(shù)量來(lái)代表程序消耗的時(shí)間,這里默認(rèn)CPU的每個(gè)單元運(yùn)行消耗的時(shí)間都是相同的。

假設(shè)算法的問(wèn)題規(guī)模為n,那么操作單元數(shù)量便用函數(shù)f(n)來(lái)表示,隨著數(shù)據(jù)規(guī)模n的增大,算法執(zhí)行時(shí)間的增長(zhǎng)率和f(n)的增長(zhǎng)率相同,這稱作為算法的漸近時(shí)間復(fù)雜度,簡(jiǎn)稱時(shí)間復(fù)雜度,記為 O(f(n))。

什么是大O

這里的大O是指什么呢,說(shuō)到時(shí)間復(fù)雜度,大家都知道O(n),O(n^2),卻說(shuō)不清什么是大O。

算法導(dǎo)論給出的解釋:大O用來(lái)表示上界的,當(dāng)用它作為算法的最壞情況運(yùn)行時(shí)間的上界,就是對(duì)任意數(shù)據(jù)輸入的運(yùn)行時(shí)間的上界。

同樣算法導(dǎo)論給出了例子:拿插入排序來(lái)說(shuō),插入排序的時(shí)間復(fù)雜度我們都說(shuō)是O(n^2) 。

輸入數(shù)據(jù)的形式對(duì)程序運(yùn)算時(shí)間是有很大影響的,在數(shù)據(jù)本來(lái)有序的情況下時(shí)間復(fù)雜度是O(n),但如果數(shù)據(jù)是逆序的話,插入排序的時(shí)間復(fù)雜度就是O(n^2),也就對(duì)于所有輸入情況來(lái)說(shuō),最壞是O(n^2) 的時(shí)間復(fù)雜度,所以稱插入排序的時(shí)間復(fù)雜度為O(n^2)。

同樣的同理再看一下快速排序,都知道快速排序是O(nlogn),但是當(dāng)數(shù)據(jù)已經(jīng)有序情況下,快速排序的時(shí)間復(fù)雜度是O(n^2) 的,所以嚴(yán)格從大O的定義來(lái)講,快速排序的時(shí)間復(fù)雜度應(yīng)該是O(n^2)。

但是我們依然說(shuō)快速排序是O(nlogn)的時(shí)間復(fù)雜度,這個(gè)就是業(yè)內(nèi)的一個(gè)默認(rèn)規(guī)定,這里說(shuō)的O代表的就是一般情況,而不是嚴(yán)格的上界。如圖所示:30e3ddca-8f11-11ec-952b-dac502259ad0.png

我們主要關(guān)心的還是一般情況下的數(shù)據(jù)形式。

面試中說(shuō)道算法的時(shí)間復(fù)雜度是多少指的都是一般情況。但是如果面試官和我們深入探討一個(gè)算法的實(shí)現(xiàn)以及性能的時(shí)候,就要時(shí)刻想著數(shù)據(jù)用例的不一樣,時(shí)間復(fù)雜度也是不同的,這一點(diǎn)是一定要注意的。

不同數(shù)據(jù)規(guī)模的差異

如下圖中可以看出不同算法的時(shí)間復(fù)雜度在不同數(shù)據(jù)輸入規(guī)模下的差異。

310e53ac-8f11-11ec-952b-dac502259ad0.png時(shí)間復(fù)雜度,不同數(shù)據(jù)規(guī)模的差異

在決定使用哪些算法的時(shí)候,不是時(shí)間復(fù)雜越低的越好(因?yàn)楹?jiǎn)化后的時(shí)間復(fù)雜度忽略了常數(shù)項(xiàng)等等),要考慮數(shù)據(jù)規(guī)模,如果數(shù)據(jù)規(guī)模很小甚至可以用O(n^2)的算法比O(n)的更合適(在有常數(shù)項(xiàng)的時(shí)候)。

就像上圖中 O(5n^2) 和 O(100n) 在n為20之前 很明顯 O(5n^2)是更優(yōu)的,所花費(fèi)的時(shí)間也是最少的。

那為什么在計(jì)算時(shí)間復(fù)雜度的時(shí)候要忽略常數(shù)項(xiàng)系數(shù)呢,也就說(shuō)O(100n) 就是O(n)的時(shí)間復(fù)雜度,O(5n^2) 就是O(n^2)的時(shí)間復(fù)雜度,而且要默認(rèn)O(n) 優(yōu)于O(n^2) 呢 ?

這里就又涉及到大O的定義,因?yàn)榇驩就是數(shù)據(jù)量級(jí)突破一個(gè)點(diǎn)且數(shù)據(jù)量級(jí)非常大的情況下所表現(xiàn)出的時(shí)間復(fù)雜度,這個(gè)數(shù)據(jù)量也就是常數(shù)項(xiàng)系數(shù)已經(jīng)不起決定性作用的數(shù)據(jù)量。

例如上圖中20就是那個(gè)點(diǎn),n只要大于20 常數(shù)項(xiàng)系數(shù)已經(jīng)不起決定性作用了。

所以我們說(shuō)的時(shí)間復(fù)雜度都是省略常數(shù)項(xiàng)系數(shù)的,是因?yàn)橐话闱闆r下都是默認(rèn)數(shù)據(jù)規(guī)模足夠的大,基于這樣的事實(shí),給出的算法時(shí)間復(fù)雜的的一個(gè)排行如下所示

O(1)常數(shù)階 < O(logn)對(duì)數(shù)階 < O(n)線性階 < O(n^2)平方階 < O(n^3)(立方階) < O(2^n) (指數(shù)階)

但是也要注意大常數(shù),如果這個(gè)常數(shù)非常大,例如10^7 ,10^9 ,那么常數(shù)就是不得不考慮的因素了。

復(fù)雜表達(dá)式的化簡(jiǎn)

有時(shí)候我們?nèi)ビ?jì)算時(shí)間復(fù)雜度的時(shí)候發(fā)現(xiàn)不是一個(gè)簡(jiǎn)單的O(n) 或者O(n^2), 而是一個(gè)復(fù)雜的表達(dá)式,例如:

O(2*n^2+10*n+1000)

那這里如何描述這個(gè)算法的時(shí)間復(fù)雜度呢,一種方法就是簡(jiǎn)化法。

去掉運(yùn)行時(shí)間中的加法常數(shù)項(xiàng) (因?yàn)槌?shù)項(xiàng)并不會(huì)因?yàn)閚的增大而增加計(jì)算機(jī)的操作次數(shù))。

O(2*n^2+10*n)

去掉常數(shù)系數(shù)(上文中已經(jīng)詳細(xì)講過(guò)為什么可以去掉常數(shù)項(xiàng)的原因)。

O(n^2+n)

只保留保留最高項(xiàng),去掉數(shù)量級(jí)小一級(jí)的n (因?yàn)閚^2 的數(shù)據(jù)規(guī)模遠(yuǎn)大于n),最終簡(jiǎn)化為:

O(n^2)

如果這一步理解有困難,那也可以做提取n的操作,變成O(n(n+1)) ,省略加法常數(shù)項(xiàng)后也就別變成了:

O(n^2)

所以最后我們說(shuō):這個(gè)算法的算法時(shí)間復(fù)雜度是O(n^2) 。

也可以用另一種簡(jiǎn)化的思路,其實(shí)當(dāng)n大于40的時(shí)候, 這個(gè)復(fù)雜度會(huì)恒小于O(3 * n^2), O(2 * n^2 + 10 * n + 1000) < O(3 * n^2),所以說(shuō)最后省略掉常數(shù)項(xiàng)系數(shù)最終時(shí)間復(fù)雜度也是O(n^2)。

O(logn)中的log是以什么為底?

平時(shí)說(shuō)這個(gè)算法的時(shí)間復(fù)雜度是logn的,那么一定是log 以2為底n的對(duì)數(shù)么?

其實(shí)不然,也可以是以10為底n的對(duì)數(shù),也可以是以20為底n的對(duì)數(shù),但我們統(tǒng)一說(shuō) logn,也就是忽略底數(shù)的描述

為什么可以這么做呢?如下圖所示:

314a779c-8f11-11ec-952b-dac502259ad0.png時(shí)間復(fù)雜度1.png

假如有兩個(gè)算法的時(shí)間復(fù)雜度,分別是log以2為底n的對(duì)數(shù)和log以10為底n的對(duì)數(shù),那么這里如果還記得高中數(shù)學(xué)的話,應(yīng)該不難理解以2為底n的對(duì)數(shù) = 以2為底10的對(duì)數(shù) * 以10為底n的對(duì)數(shù)

而以2為底10的對(duì)數(shù)是一個(gè)常數(shù),在上文已經(jīng)講述了我們計(jì)算時(shí)間復(fù)雜度是忽略常數(shù)項(xiàng)系數(shù)的。

抽象一下就是在時(shí)間復(fù)雜度的計(jì)算過(guò)程中,log以i為底n的對(duì)數(shù)等于log 以j為底n的對(duì)數(shù),所以忽略了i,直接說(shuō)是logn。

這樣就應(yīng)該不難理解為什么忽略底數(shù)了。

舉一個(gè)例子

通過(guò)這道面試題目,來(lái)分析一下時(shí)間復(fù)雜度。題目描述:找出n個(gè)字符串中相同的兩個(gè)字符串(假設(shè)這里只有兩個(gè)相同的字符串)。

如果是暴力枚舉的話,時(shí)間復(fù)雜度是多少呢,是O(n^2)么?

這里一些同學(xué)會(huì)忽略了字符串比較的時(shí)間消耗,這里并不像int 型數(shù)字做比較那么簡(jiǎn)單,除了n^2 次的遍歷次數(shù)外,字符串比較依然要消耗m次操作(m也就是字母串的長(zhǎng)度),所以時(shí)間復(fù)雜度是O(m * n * n)。

接下來(lái)再想一下其他解題思路。

先排對(duì)n個(gè)字符串按字典序來(lái)排序,排序后n個(gè)字符串就是有序的,意味著兩個(gè)相同的字符串就是挨在一起,然后在遍歷一遍n個(gè)字符串,這樣就找到兩個(gè)相同的字符串了。

那看看這種算法的時(shí)間復(fù)雜度,快速排序時(shí)間復(fù)雜度為O(nlogn),依然要考慮字符串的長(zhǎng)度是m,那么快速排序每次的比較都要有m次的字符比較的操作,就是O(m * n * logn) 。

之后還要遍歷一遍這n個(gè)字符串找出兩個(gè)相同的字符串,別忘了遍歷的時(shí)候依然要比較字符串,所以總共的時(shí)間復(fù)雜度是 O(m * n * logn + n * m)。

我們對(duì)O(m * n * logn + n * m) 進(jìn)行簡(jiǎn)化操作,把m * n提取出來(lái)變成 O(m * n * (logn + 1)),再省略常數(shù)項(xiàng)最后的時(shí)間復(fù)雜度是 O(m * n * logn)。

最后很明顯O(m * n * logn) 要優(yōu)于O(m * n * n)!

所以先把字符串集合排序再遍歷一遍找到兩個(gè)相同字符串的方法要比直接暴力枚舉的方式更快。

這就是我們通過(guò)分析兩種算法的時(shí)間復(fù)雜度得來(lái)的。

當(dāng)然這不是這道題目的最優(yōu)解,我僅僅是用這道題目來(lái)講解一下時(shí)間復(fù)雜度。

總結(jié)

本篇講解了什么是時(shí)間復(fù)雜度,復(fù)雜度是用來(lái)干什么,以及數(shù)據(jù)規(guī)模對(duì)時(shí)間復(fù)雜度的影響。

還講解了被大多數(shù)同學(xué)忽略的大O的定義以及l(fā)og究竟是以誰(shuí)為底的問(wèn)題。

再分析了如何簡(jiǎn)化復(fù)雜的時(shí)間復(fù)雜度,最后舉一個(gè)具體的例子,把本篇的內(nèi)容串起來(lái)。

相信看完本篇,大家對(duì)時(shí)間復(fù)雜度的認(rèn)識(shí)會(huì)深刻很多!

原文標(biāo)題:關(guān)于時(shí)間復(fù)雜度,你不知道的都在這里

文章出處:【微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
審核編輯:湯梓紅


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4607

    瀏覽量

    92826
  • 軟件
    +關(guān)注

    關(guān)注

    69

    文章

    4921

    瀏覽量

    87394
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3785

    瀏覽量

    81002

原文標(biāo)題:關(guān)于時(shí)間復(fù)雜度,你不知道的都在這里

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    時(shí)間復(fù)雜度為 O(n^2) 的排序算法

    作者:京東保險(xiǎn) 王奕龍 對(duì)于小規(guī)模數(shù)據(jù),我們可以選用時(shí)間復(fù)雜度為 O(n2) 的排序算法。因?yàn)?b class='flag-5'>時(shí)間復(fù)雜度并不代表實(shí)際代碼的執(zhí)行時(shí)間,它省去了
    的頭像 發(fā)表于 10-19 16:31 ?1136次閱讀
    <b class='flag-5'>時(shí)間</b><b class='flag-5'>復(fù)雜度</b>為 O(n^2) 的排序算法

    PCB與PCBA工藝復(fù)雜度的量化評(píng)估與應(yīng)用初探!

    , 不知道如何區(qū)分普通和復(fù)雜的PCB和 PCBA的設(shè)計(jì),并采用什么樣的方式來(lái)處理。 基于上述考慮, 我們參考了業(yè) 界已有的作法, 設(shè)計(jì)了一個(gè)PCB 和 PCBA的工藝復(fù)雜度計(jì)算公式以解決這 方面
    發(fā)表于 06-14 11:15

    JEM軟件復(fù)雜度的增加情況

    這篇文檔展示了幾個(gè)機(jī)構(gòu)關(guān)于JEM軟件復(fù)雜度的增加情況的看法,特別提出來(lái)創(chuàng)立一個(gè)新的Ad-hoc組,研究降低軟件一般性復(fù)雜度的可能方法。
    發(fā)表于 07-19 08:25

    時(shí)間復(fù)雜度是指什么

    原理->微機(jī)原理->軟件工程,編譯原理,數(shù)據(jù)庫(kù)數(shù)據(jù)結(jié)構(gòu)1.時(shí)間復(fù)雜度時(shí)間復(fù)雜度是指執(zhí)行算法所需要的計(jì)算工作量,因?yàn)檎麄€(gè)算法的執(zhí)行時(shí)間與基本操
    發(fā)表于 07-22 10:01

    各種排序算法的時(shí)間空間復(fù)雜度、穩(wěn)定性

    各種排序算法的時(shí)間空間復(fù)雜度、穩(wěn)定性一、排序算法分類:二、排序算法比較:注:1、歸并排序可以通過(guò)手搖算法將空間復(fù)雜度降到O(1),但是時(shí)間復(fù)雜度
    發(fā)表于 12-21 07:48

    圖像復(fù)雜度對(duì)信息隱藏性能影響分析

    針對(duì)信息隱藏中載體圖像的差異性,提出一種圖像復(fù)雜度評(píng)價(jià)方法,綜合考慮圖像的壓縮特性以及圖像紋理能量作為圖像復(fù)雜度指標(biāo),并基于閾值劃分準(zhǔn)則對(duì)栽體圖像進(jìn)行復(fù)雜度分類,以幾種經(jīng)典的基于直方圖的幾種無(wú)損隱藏
    發(fā)表于 11-14 09:57 ?5次下載

    如何求遞歸算法的時(shí)間復(fù)雜度

    那么我通過(guò)一道簡(jiǎn)單的面試題,模擬面試的場(chǎng)景,來(lái)帶大家逐步分析遞歸算法的時(shí)間復(fù)雜度,最后找出最優(yōu)解,來(lái)看看同樣是遞歸,怎么就寫成了O(n)的代碼。
    的頭像 發(fā)表于 07-13 11:30 ?2257次閱讀

    如何求遞歸算法的時(shí)間復(fù)雜度

    相信很多同學(xué)對(duì)遞歸算法的時(shí)間復(fù)雜度都很模糊,那么這篇Carl來(lái)給大家通透的講一講。
    的頭像 發(fā)表于 07-13 11:33 ?1604次閱讀

    算法之空間復(fù)雜度

    算法之空間復(fù)雜度:衡量一個(gè)算法運(yùn)行需要開(kāi)辟的額外空間
    的頭像 發(fā)表于 08-31 10:29 ?1600次閱讀

    常見(jiàn)機(jī)器學(xué)習(xí)算法的計(jì)算復(fù)雜度

    時(shí)間復(fù)雜度不是測(cè)量一個(gè)算法或一段代碼在某個(gè)機(jī)器或者條件下運(yùn)行所花費(fèi)的時(shí)間。時(shí)間復(fù)雜度一般指時(shí)間
    發(fā)表于 10-02 12:45 ?812次閱讀

    算法時(shí)空復(fù)雜度分析實(shí)用指南1

    我以前的文章主要都是講解算法的原理和解題的思維,對(duì)時(shí)間復(fù)雜度和空間復(fù)雜度的分析經(jīng)常一筆帶過(guò),主要是基于以下兩個(gè)原因:
    的頭像 發(fā)表于 04-12 14:37 ?509次閱讀
    算法時(shí)空<b class='flag-5'>復(fù)雜度</b>分析實(shí)用指南1

    算法時(shí)空復(fù)雜度分析實(shí)用指南2

    類似的,想想之前說(shuō)的數(shù)據(jù)結(jié)構(gòu)擴(kuò)容的場(chǎng)景,也許`N`次操作中的某一次操作恰好觸發(fā)了擴(kuò)容,導(dǎo)致時(shí)間復(fù)雜度提高,但總的時(shí)間復(fù)雜度依然保持在`O(N)`,所以均攤到每一次操作上,其平均
    的頭像 發(fā)表于 04-12 14:38 ?527次閱讀
    算法時(shí)空<b class='flag-5'>復(fù)雜度</b>分析實(shí)用指南2

    算法時(shí)空復(fù)雜度分析實(shí)用指南(上)

    本文會(huì)篇幅較長(zhǎng),會(huì)涵蓋如下幾點(diǎn): 1、Big O 表示法的幾個(gè)基本特點(diǎn)。 2、非遞歸算法中的時(shí)間復(fù)雜度分析。 3、數(shù)據(jù)結(jié)構(gòu) API 的效率衡量方法(攤還分析)。 4、遞歸算法的時(shí)間/空間
    的頭像 發(fā)表于 04-19 10:34 ?811次閱讀
    算法時(shí)空<b class='flag-5'>復(fù)雜度</b>分析實(shí)用指南(上)

    算法時(shí)空復(fù)雜度分析實(shí)用指南(下)

    Big O 表示法的幾個(gè)基本特點(diǎn)。 2、非遞歸算法中的時(shí)間復(fù)雜度分析。 3、數(shù)據(jù)結(jié)構(gòu) API 的效率衡量方法(攤還分析)。 4、遞歸算法的時(shí)間/空間復(fù)雜度的分析方法,
    的頭像 發(fā)表于 04-19 10:35 ?688次閱讀
    算法時(shí)空<b class='flag-5'>復(fù)雜度</b>分析實(shí)用指南(下)

    如何計(jì)算時(shí)間復(fù)雜度

    1 算法與時(shí)間復(fù)雜度 算法(Algorithm)是求解一個(gè)問(wèn)題需要遵循的,被清楚指定的簡(jiǎn)單指令的集合。 算法一旦確定,那么下一步就要確定該算法將需要多少時(shí)間和空間等資源,如果一個(gè)算法需要一兩年的
    的頭像 發(fā)表于 10-13 11:19 ?2965次閱讀
    如何計(jì)算<b class='flag-5'>時(shí)間</b><b class='flag-5'>復(fù)雜度</b>
    RM新时代网站-首页