最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

關(guān)于遞歸算法的時(shí)間復(fù)雜度,你還不夠了解!

2021-07-29 12:49 作者:代碼隨想錄  | 我要投稿

大家好,我是Carl

本篇通過一道面試題,一個(gè)面試場景,來好好分析一下如何求遞歸算法的時(shí)間復(fù)雜度。

相信很多同學(xué)對遞歸算法的時(shí)間復(fù)雜度都很模糊,那么這篇Carl來給大家通透的講一講。

同一道題目,同樣使用遞歸算法,有的同學(xué)會(huì)寫出了O(n)的代碼,有的同學(xué)就寫出了O(logn)的代碼。

這是為什么呢?

如果對遞歸的時(shí)間復(fù)雜度理解的不夠深入的話,就會(huì)這樣!

那么我通過一道簡單的面試題,模擬面試的場景,來帶大家逐步分析遞歸算法的時(shí)間復(fù)雜度,最后找出最優(yōu)解,來看看同樣是遞歸,怎么就寫成了O(n)的代碼。

面試題:求x的n次方

想一下這么簡單的一道題目,代碼應(yīng)該如何寫呢。最直觀的方式應(yīng)該就是,一個(gè)for循環(huán)求出結(jié)果,代碼如下:

int?function1(int?x,?int?n)?{
????int?result?=?1;??//?注意?任何數(shù)的0次方等于1
????for?(int?i?=?0;?i?<?n;?i++)?{
????????result?=?result?*?x;
????}
????return?result;
}

時(shí)間復(fù)雜度為O(n),此時(shí)面試官會(huì)說,有沒有效率更好的算法呢。

如果此時(shí)沒有思路,不要說:我不會(huì),我不知道了等等。

可以和面試官探討一下,詢問:“可不可以給點(diǎn)提示”。面試官提示:“考慮一下遞歸算法”。

那么就可以寫出了如下這樣的一個(gè)遞歸的算法,使用遞歸解決了這個(gè)問題。

int?function2(int?x,?int?n)?{
????if?(n?==?0)?{
????????return?1;?//?return?1?同樣是因?yàn)?次方是等于1的
????}
????return?function2(x,?n?-?1)?*?x;
}

面試官問:“那么這個(gè)代碼的時(shí)間復(fù)雜度是多少?”。

一些同學(xué)可能一看到遞歸就想到了O(logn),其實(shí)并不是這樣,遞歸算法的時(shí)間復(fù)雜度本質(zhì)上是要看:?遞歸的次數(shù) * 每次遞歸中的操作次數(shù)。

那再來看代碼,這里遞歸了幾次呢?

每次n-1,遞歸了n次時(shí)間復(fù)雜度是O(n),每次進(jìn)行了一個(gè)乘法操作,乘法操作的時(shí)間復(fù)雜度一個(gè)常數(shù)項(xiàng)O(1),所以這份代碼的時(shí)間復(fù)雜度是 n * 1 = O(n)。

這個(gè)時(shí)間復(fù)雜度就沒有達(dá)到面試官的預(yù)期。于是又寫出了如下的遞歸算法的代碼:

int?function3(int?x,?int?n)?{
????if?(n?==?0)?{
????????return?1;
????}
????if?(n?%?2?==?1)?{
????????return?function3(x,?n?/?2)?*?function3(x,?n?/?2)*x;
????}
????return?function3(x,?n?/?2)?*?function3(x,?n?/?2);
}

面試官看到后微微一笑,問:“這份代碼的時(shí)間復(fù)雜度又是多少呢?” 此刻有些同學(xué)可能要陷入了沉思了。

我們來分析一下,首先看遞歸了多少次呢,可以把遞歸抽象出一顆滿二叉樹。剛剛同學(xué)寫的這個(gè)算法,可以用一顆滿二叉樹來表示(為了方便表示,選擇n為偶數(shù)16),如圖:


當(dāng)前這顆二叉樹就是求x的n次方,n為16的情況,n為16的時(shí)候,進(jìn)行了多少次乘法運(yùn)算呢?

這棵樹上每一個(gè)節(jié)點(diǎn)就代表著一次遞歸并進(jìn)行了一次相乘操作,所以進(jìn)行了多少次遞歸的話,就是看這棵樹上有多少個(gè)節(jié)點(diǎn)。

熟悉二叉樹話應(yīng)該知道如何求滿二叉樹節(jié)點(diǎn)數(shù)量,這顆滿二叉樹的節(jié)點(diǎn)數(shù)量就是2^3 + 2^2 + 2^1 + 2^0 = 15,可以發(fā)現(xiàn):這其實(shí)是等比數(shù)列的求和公式,這個(gè)結(jié)論在二叉樹相關(guān)的面試題里也經(jīng)常出現(xiàn)

這么如果是求x的n次方,這個(gè)遞歸樹有多少個(gè)節(jié)點(diǎn)呢,如下圖所示:(m為深度,從0開始)


時(shí)間復(fù)雜度忽略掉常數(shù)項(xiàng)-1之后,這個(gè)遞歸算法的時(shí)間復(fù)雜度依然是O(n)。對,你沒看錯(cuò),依然是O(n)的時(shí)間復(fù)雜度!

此時(shí)面試官就會(huì)說:“這個(gè)遞歸的算法依然還是O(n)啊”, 很明顯沒有達(dá)到面試官的預(yù)期。

那么O(logn)的遞歸算法應(yīng)該怎么寫呢?

想一想剛剛給出的那份遞歸算法的代碼,是不是有哪里比較冗余呢,其實(shí)有重復(fù)計(jì)算的部分。

于是又寫出如下遞歸算法的代碼:

int?function4(int?x,?int?n)?{
????if?(n?==?0)?{
????????return?1;
????}
????int?t?=?function4(x,?n?/?2);//?這里相對于function3,是把這個(gè)遞歸操作抽取出來
????if?(n?%?2?==?1)?{
????????return?t?*?t?*?x;
????}
????return?t?*?t;
}

再來看一下現(xiàn)在這份代碼時(shí)間復(fù)雜度是多少呢?

依然還是看他遞歸了多少次,可以看到這里僅僅有一個(gè)遞歸調(diào)用,且每次都是n/2 ,所以這里我們一共調(diào)用了log以2為底n的對數(shù)次。

每次遞歸了做都是一次乘法操作,這也是一個(gè)常數(shù)項(xiàng)的操作,那么這個(gè)遞歸算法的時(shí)間復(fù)雜度才是真正的O(logn)

此時(shí)大家最后寫出了這樣的代碼并且將時(shí)間復(fù)雜度分析的非常清晰,相信面試官是比較滿意的。

總結(jié)

對于遞歸的時(shí)間復(fù)雜度,畢竟初學(xué)者有時(shí)候會(huì)迷糊,刷過很多題的老手依然迷糊。

本篇我用一道非常簡單的面試題目:求x的n次方,來逐步分析遞歸算法的時(shí)間復(fù)雜度,注意不要一看到遞歸就想到了O(logn)!

同樣使用遞歸,有的同學(xué)可以寫出O(logn)的代碼,有的同學(xué)還可以寫出O(n)的代碼。

對于function3 這樣的遞歸實(shí)現(xiàn),很容易讓人感覺這是O(logn)的時(shí)間復(fù)雜度,其實(shí)這是O(n)的算法!

int?function3(int?x,?int?n)?{
????if?(n?==?0)?{
????????return?1;
????}
????if?(n?%?2?==?1)?{
????????return?function3(x,?n?/?2)?*?function3(x,?n?/?2)*x;
????}
????return?function3(x,?n?/?2)?*?function3(x,?n?/?2);
}

可以看出這道題目非常簡單,但是又很考究算法的功底,特別是對遞歸的理解,這也是我面試別人的時(shí)候用過的一道題,所以整個(gè)情景我才寫的如此逼真,哈哈。

大廠面試的時(shí)候最喜歡用“簡單題”來考察候選人的算法功底,注意這里的“簡單題”可并不一定真的簡單哦!

如果認(rèn)真讀完本篇,相信大家對遞歸算法的有一個(gè)新的認(rèn)識的,同一道題目,同樣是遞歸,效率可是不一樣的!

Hello,我是Carl,哈工大師兄,獲得過ACM亞洲區(qū)獎(jiǎng)牌,先后在BAT中的兩家采坑,一位文舞雙全的程序員。

我的刷題攻略開源在Github上:https://github.com/youngyangyang04/leetcode-master,循序漸進(jìn)的刷題循序,詳細(xì)的題目講解,支持C++,Java,Python,Go,JS等多門語言版本,相信你會(huì)發(fā)現(xiàn)詳見恨晚!

覺得不錯(cuò)的話,還請小伙伴 點(diǎn)贊 支持下,希望能幫助到更多同學(xué) ????

關(guān)于遞歸算法的時(shí)間復(fù)雜度,你還不夠了解!的評論 (共 條)

分享到微博請遵守國家法律
灵山县| 长宁县| 抚州市| 遂平县| 纳雍县| 巧家县| 湘乡市| 宜良县| 新绛县| 金华市| 如东县| 东乌珠穆沁旗| 华亭县| 苏州市| 九龙县| 普安县| 瓦房店市| 桐柏县| 称多县| 无极县| 新昌县| 文安县| 南涧| 六枝特区| 驻马店市| 历史| 甘德县| 三都| 五家渠市| 盐源县| 缙云县| 连云港市| 股票| 永城市| 固始县| 抚州市| 图木舒克市| 年辖:市辖区| 洱源县| 金门县| 湖北省|