斐波那契數(shù)的時(shí)間復(fù)雜度、空間復(fù)雜度詳解

斐波那契數(shù)列:
f(n)=f(n-1)+f(n-2)(n>2) f(0)=1;f(1)=1;
即有名的兔子繁衍問題
在本篇文章我將會(huì)給出三種解法

方法一: 遞歸

static int f1(int i) {
        if (i == 1 || i == 2)
            return 1;
        else
            return f1(i - 1) + f1(i - 2);
    }

1.時(shí)間復(fù)雜度 O(2^n)
首先可以根據(jù)函數(shù)遞歸執(zhí)行順序畫出下圖的二叉樹結(jié)構(gòu)(假設(shè)求第五個(gè)斐波那契數(shù))

image.png

2.空間復(fù)雜度 O(1)


image.png

①-③:調(diào)用Fib(5),首先需調(diào)用Fib(4),Fib(4)要先調(diào)用Fib(3)溯壶,逐步調(diào)用直至返回Fib(2)的值1,F(xiàn)ib執(zhí)行結(jié)束甫男,所創(chuàng)建空間銷毀且改。此時(shí)Fib(5)、Fib(4)板驳、Fib(3)均未調(diào)用結(jié)束钾虐,程序共占用4個(gè)函數(shù)棧幀空間。

④-⑨:Fib(2)執(zhí)行結(jié)束笋庄,接下來調(diào)用Fib(1)效扫,創(chuàng)建一個(gè)函數(shù)棧幀空間倔监,調(diào)用結(jié)束返回1后,該空間銷毀菌仁,此時(shí)可得到Fib(3)=2浩习,通過第⑦步返回Fib(3)的值,第⑧步同樣創(chuàng)建空間再次調(diào)用Fib(2)济丘,調(diào)用結(jié)束銷毀空間谱秽,此時(shí)可得到Fib(4)=3,通過第⑨步返回Fib(4)的值摹迷,此過程最大占用4個(gè)函數(shù)棧幀空間疟赊。

⑩-···:最后和上面一樣,調(diào)用Fib(3)峡碉,將返回值傳給Fib(5)的模塊近哟,最終得到Fib(5)=5。

整個(gè)程序執(zhí)行過程中鲫寄,最多占用4個(gè)函數(shù)棧幀空間的大小吉执,設(shè)一個(gè)函數(shù)棧幀空間為C
因此可得知當(dāng)n=5時(shí),該程序空間復(fù)雜度為O(4C)=>O(1)
當(dāng)求第n個(gè)斐波那契數(shù)時(shí)地来,程序空間復(fù)雜度為O(n-1)C (n是常數(shù))=>O(1)

方法二:循環(huán)

image.png
static int f2(int n) {
        int count = 1;
        int Fn_1 = 1;
        int Fn_2 = 1;
        while (n > 2) {
            Fn_2 = Fn_1;
            Fn_1 = count;
            count = Fn_1 + Fn_2;
            n--;
        }
        return count;
    }

1.時(shí)間復(fù)雜度 O(n)
程序中循環(huán)了n-2次戳玫,時(shí)間復(fù)雜度為O(n-2),保留最高階時(shí)間復(fù)雜度為O(n)

2.空間復(fù)雜度 O(1)
該程序中創(chuàng)建了3個(gè)變量,即創(chuàng)建了3個(gè)內(nèi)存空間未斑,空間復(fù)雜度為O(3)即O(1)

方法三:尾遞歸

image.png
int fib(int n) {
    int pre = 1;
    int ppre = 0;
    int ret = 0;
    for (int i = 1; i <= n; i++) {
        ret = pre + ppre;
        ppre = pre;
        pre = ret;
    }
    return ret;
}

1.時(shí)間復(fù)雜度 O(n)
根據(jù)尾遞歸的圖解可看出咕宿,計(jì)算Fib(1,1,5)時(shí),函數(shù)調(diào)用了3次蜡秽,那么計(jì)算Fib(1,1,n)時(shí)府阀,函數(shù)將調(diào)用n-2次,
由此可得時(shí)間復(fù)雜度為O(n-2)即O(n)载城。

2.空間復(fù)雜度 O(n)


image.png

尾遞歸的方法,需開辟n-2個(gè)空間费就,空間復(fù)雜度為O(n-2)即O(n)诉瓦。

方法四:記憶化搜索(Memory Search)

記憶化搜索,即在搜索過程中記錄下搜索結(jié)果力细,在下次的搜索過程中如果算出過這個(gè)結(jié)果睬澡,就可以直接拿來用。
時(shí)間復(fù)雜度O(N), 空間復(fù)雜度O(n)

/**
     * memory search
     * 遞歸
     * 時(shí)間復(fù)雜度O(N), 空間復(fù)雜度O(n)
     * @param n
     * @return
     */
    public static int fib_ms(int n){
        if(n==0){
            return 0;
        }
        if(n == 1 || n == 2){
            return 1;
        }
        int[] memory = new int[n+1];
        if(memory[n] != 0){
            return memory[n];
        }
        memory[n] = fib_ms(n-1) + fib_ms(n-2);
        return memory[n];
    }

方法五:動(dòng)態(tài)規(guī)劃(Dynamic Programming)

非遞歸眠蚂,減少了系統(tǒng)棧的建立煞聪,比記憶化搜索還快,將原問題拆解成若干子問題逝慧,同時(shí)保存子問題的答案昔脯,使得每個(gè)子問題只求解一次啄糙,最終獲得原問題的答案
時(shí)間復(fù)雜度O(N), 空間復(fù)雜度O(1)

/**
     * dynamic programming
     * 非遞歸,減少了系統(tǒng)棧的建立云稚,比記憶化搜索還快
     * 將原問題拆解成若干子問題隧饼,同時(shí)保存子問題的答案,使得每個(gè)子問題只求解一次静陈,最終獲得原問題的答案
     * 時(shí)間復(fù)雜度O(N), 空間復(fù)雜度O(1)
     * @param n
     * @return
     */
    public static int fib_dp(int n){
        if(n==0){
            return 0;
        }
        if(n == 1 || n == 2){
            return 1;
        }
        int pre = 1;
        int ppre = 1;
        int result = 0;
        for(int i=3; i<=n; i++){
            result = pre + ppre;
            ppre = pre;
            pre = result;
        }
        return result;
    }

————————————————
原文鏈接:https://blog.csdn.net/lxf_style/java/article/details/80458519

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末燕雁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鲸拥,更是在濱河造成了極大的恐慌拐格,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刑赶,死亡現(xiàn)場離奇詭異捏浊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)角撞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門呛伴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谒所,你說我怎么就攤上這事热康。” “怎么了劣领?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵姐军,是天一觀的道長。 經(jīng)常有香客問我尖淘,道長奕锌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任村生,我火速辦了婚禮惊暴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趁桃。我一直安慰自己辽话,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布卫病。 她就那樣靜靜地躺著油啤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蟀苛。 梳的紋絲不亂的頭發(fā)上益咬,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音帜平,去河邊找鬼幽告。 笑死梅鹦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的评腺。 我是一名探鬼主播帘瞭,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒿讥!你這毒婦竟也來了蝶念?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤芋绸,失蹤者是張志新(化名)和其女友劉穎媒殉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摔敛,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡廷蓉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了马昙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桃犬。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖行楞,靈堂內(nèi)的尸體忽然破棺而出攒暇,到底是詐尸還是另有隱情,我是刑警寧澤子房,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布形用,位于F島的核電站,受9級(jí)特大地震影響证杭,放射性物質(zhì)發(fā)生泄漏田度。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一解愤、第九天 我趴在偏房一處隱蔽的房頂上張望镇饺。 院中可真熱鬧,春花似錦送讲、人聲如沸奸笤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揭保。三九已至肥橙,卻和暖如春魄宏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背存筏。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工宠互, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留味榛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓予跌,卻偏偏與公主長得像搏色,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子券册,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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