算法系列:Objective-C四種算法求斐波那契數(shù)列

什么是斐波那契數(shù)列?

摘自《維基百科》
?
斐波那契數(shù)列意大利語:Successione di Fibonacci)瘩燥,又譯為菲波拿契數(shù)列服猪、菲波那西數(shù)列褂傀、斐波那契數(shù)列黃金分割數(shù)列您访。
?
數(shù)學上呻逆,費波那契數(shù)列是以遞歸的方法來定義:F(1)=1,F(xiàn)(2)=1, F(3)=2,F(n)=F(n-1)+F(n-2)(n>=4驰吓,n∈N*)
?
用文字來說,就是費波那契數(shù)列由0和1開始,之后的費波那契系數(shù)就是由之前的兩數(shù)相加而得出辆布。首幾個費波那契系數(shù)是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……

摘自《百度百科》
?
斐波那契數(shù)列(Fibonacci sequence),又稱黃金分割數(shù)列茶鉴、因數(shù)學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入锋玲,故又稱為“兔子數(shù)列”,指的是這樣一個數(shù)列:1涵叮、1惭蹂、2、3割粮、5盾碗、8、13穆刻、21置尔、34、……在數(shù)學上氢伟,斐波納契數(shù)列以如下被以遞推的方法定義:F(1)=1榜轿,F(xiàn)(2)=1, F(3)=2,F(n)=F(n-1)+F(n-2)(n>=4,n∈N*)在現(xiàn)代物理朵锣、準晶體結(jié)構(gòu)谬盐、化學等領(lǐng)域,斐波納契數(shù)列都有直接的應(yīng)用诚些,為此飞傀,美國數(shù)學會從1963年起出版了以《斐波納契數(shù)列季刊》為名的一份數(shù)學雜志,用于專門刊載這方面的研究成果诬烹。
?
定義:
?
斐波那契數(shù)列指的是這樣一個數(shù)列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233砸烦,377,610绞吁,987幢痘,1597,2584家破,4181颜说,6765购岗,10946,17711门粪,28657喊积,46368........
?
這個數(shù)列從第3項開始,每一項都等于前兩項之和玄妈。
?
斐波那契數(shù)列的定義者乾吻,是意大利數(shù)學家列昂納多·斐波那契(Leonardo Fibonacci),生于公元1170年措近,卒于1250年溶弟,籍貫是比薩。他被人稱作“比薩的列昂納多”瞭郑。1202年辜御,他撰寫了《算盤全書》(Liber Abacci)一書。他是第一個研究了印度和阿拉伯數(shù)學理論的歐洲人屈张。他的父親被比薩的一家商業(yè)團體聘任為外交領(lǐng)事擒权,派駐地點相當于今日的阿爾及利亞地區(qū),列昂納多因此得以在一個阿拉伯老師的指導下研究數(shù)學阁谆。他還曾在埃及碳抄、敘利亞、希臘场绿、西西里普羅旺斯等地研究數(shù)學剖效。



看了這么多簡介之后,其實說的簡單點斐波那契數(shù)列就是一系列數(shù)字焰盗,從第三項開始當前項等于前兩項之和璧尸。下面我用OC給出斐波那契數(shù)列

第一種方式:

斐波那契數(shù)列遞歸調(diào)用,指數(shù)級增長2^n熬拒。遞歸方式效率低爷光,時間復雜度是指數(shù)級的。

/**
 斐波那契數(shù)列遞歸調(diào)用澎粟,指數(shù)級增長2^n
 */
- (NSUInteger)Fibonacci:(NSUInteger)n {
    if (n < 2) {
        return n;
    }
    else {
        return [self Fibonacci:n-1] + [self Fibonacci:n-2];
    }
}


第二種方式:

用數(shù)組保存之前計算過的結(jié)果蛀序,減少大量重復計算,這樣算法復雜度優(yōu)化為 O(n)活烙。

- (NSUInteger)Fibonacci2:(NSUInteger)n {
    if (n < 2) {
        return n;
    }
    else {
        NSMutableArray *array = [NSMutableArray arrayWithCapacity:n + 1];
        array[0] = @(0);
        array[1] = @(1);
        
        for (int i = 2; i < array.count; i++) {
            array[i] = @([array[i - 1] unsignedIntegerValue] + [array[i - 2] unsignedIntegerValue]);
        }
        
        return [array[n] unsignedIntegerValue];
    }
}


第三種方式:

同樣是斐波那契數(shù)列徐裸,由于實際只有前兩個計算結(jié)果有用,我們可以使用中間變量來存儲啸盏,這樣就不用創(chuàng)建數(shù)組以節(jié)省空間重贺。同樣算法復雜度優(yōu)化為 O(n)。

- (NSUInteger)Fibonacci3:(NSUInteger)n {
//    NSDate *now1 = [NSDate date];
    if (n < 2) {
        return n;
    }
    else {
        NSUInteger a = 0, b = 1;
        for (int i = 1; i < n; i++) {
            b = a + b;
            a = b - a;
        }
//        NSLog(@"fb3耗時:%lf", [now1 timeIntervalSinceNow]);
        return b;
    }
}


第四種方式:

通過使用矩陣乘方的算法來優(yōu)化斐波那契數(shù)列算法。算法的時間復雜度可以優(yōu)化為O(log n)檬姥。

// 計算二階矩陣的相乘
- (NSArray *)multiArrayA:(NSArray *)arrayA arrayB:(NSArray *)arrayB {
    
    // 定義一個空的二階矩陣
    NSMutableArray *arrayC = [NSMutableArray arrayWithObjects:@[@0,@0].mutableCopy,@[@0,@0].mutableCopy, nil];
    
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                NSNumber *numA = arrayA[i][k];
                NSNumber *numB = arrayB[k][j];
                NSNumber *numC = arrayC[i][j];
                
                // 新二階矩陣的值計算
                numC = @(numC.unsignedIntegerValue + numA.unsignedIntegerValue * numB.unsignedIntegerValue);
                
                [arrayC[i] replaceObjectAtIndex:j withObject:numC];
            }
        }
    }
    return arrayC;
}

- (NSUInteger)Fibonacci4:(NSUInteger)n {
    
//    NSDate *now2 = [NSDate date];
    // 結(jié)果矩陣  最開始的結(jié)果矩陣也可以看做是1,因為這個矩陣和任意二階A矩陣相乘結(jié)果都是A
    NSArray *arrayA = [NSArray arrayWithObjects:@[@1,@0],@[@0,@1], nil];
    
    // 元矩陣粉怕,這里可以把元矩陣看做是2**0=1
    NSArray *arrayB = [NSArray arrayWithObjects:@[@1,@1],@[@1,@0], nil];
    
    while (n) {
        // 取n的二進制的最后一位和1做與運算健民,如果最后一位是1,則進入if體內(nèi)部
        if (n & 1) {
            // 如果在該位置n的二進制為1贫贝,則計算ans和base矩陣
            arrayA = [self multiArrayA:arrayA arrayB:arrayB];
        }
        // base矩陣相乘秉犹,相當于初始base矩陣的冪*2
        arrayB = [self multiArrayA:arrayB arrayB:arrayB];
        // n的二進制往右移一位
        n >>= 1;
    }
    NSNumber *result = arrayA[0][1]; // 最后獲取到的二階矩陣的[0][1]即f(n)的值
//    NSLog(@"fb4耗時:%lf", [now2 timeIntervalSinceNow]);
    return result.unsignedIntegerValue;
}


參考資料

算法之矩陣計算斐波那契數(shù)列

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市稚晚,隨后出現(xiàn)的幾起案子崇堵,更是在濱河造成了極大的恐慌,老刑警劉巖客燕,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸳劳,死亡現(xiàn)場離奇詭異,居然都是意外死亡也搓,警方通過查閱死者的電腦和手機赏廓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來傍妒,“玉大人幔摸,你說我怎么就攤上這事〔罚” “怎么了既忆?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嗦玖。 經(jīng)常有香客問我患雇,道長,這世上最難降的妖魔是什么踏揣? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任庆亡,我火速辦了婚禮,結(jié)果婚禮上捞稿,老公的妹妹穿的比我還像新娘又谋。我一直安慰自己,他們只是感情好娱局,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布彰亥。 她就那樣靜靜地躺著,像睡著了一般衰齐。 火紅的嫁衣襯著肌膚如雪任斋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天耻涛,我揣著相機與錄音废酷,去河邊找鬼瘟檩。 笑死,一個胖子當著我的面吹牛澈蟆,可吹牛的內(nèi)容都是我干的墨辛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼趴俘,長吁一口氣:“原來是場噩夢啊……” “哼睹簇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寥闪,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤太惠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疲憋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凿渊,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年柜某,在試婚紗的時候發(fā)現(xiàn)自己被綠了嗽元。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡喂击,死狀恐怖剂癌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翰绊,我是刑警寧澤佩谷,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站监嗜,受9級特大地震影響谐檀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜裁奇,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一桐猬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刽肠,春花似錦溃肪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至躺涝,卻和暖如春厨钻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工夯膀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诗充,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓诱建,卻偏偏與公主長得像其障,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涂佃,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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