成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

青蛙跳臺階,能寫一個復雜度更低的解法嗎?

開發 前端
今天的內容是關于一道算法題—青蛙跳臺階。這是一個面試很喜歡考的題,看到它,大部分人腦海中應該立馬出現:斐波那契亞數列—遞歸—f(n)=f(n-1)+f(n-2)。

大家好,我是年年!今天的內容是關于一道算法題——青蛙跳臺階。這是一個面試很喜歡考的題,看到它,大部分人腦海中應該立馬出現:斐波那契亞數列——遞歸——f(n)=f(n-1)+f(n-2)。

但輔導的小伙伴上周在面試中遇到的問題是:除了遞歸,能不能寫出別的解法,降低算法的時間復雜度。這篇文章給出這道題的更優解。

題目

一只青蛙一次可以跳上1級臺階,也可以跳上2級臺階。求該青蛙跳上一個n級的臺階總共有多少種跳法?

分析

這是一個最基礎的動態規劃類問題,首先來講一下思路:當n較小時,可以直接枚舉得到結果:

  1. n=1時,青蛙僅有直接跳上一級臺階這種跳法,即一種跳法;
  2. n=2時,青蛙可以先跳 上 1 級,然后再跳 上 1 級到達2級臺階,;也可以直接跳 2 級臺階,即一共有兩種解法;

當n較大時,去枚舉不現實了。但可以想象一下青蛙“最后一跳”有哪些情況:因為青蛙一次可以跳1個或2個臺階,所以只可能是兩種情況:從n-1級跳1級上去,以及從n-2階的位置跳2級上去。我們想要知道跳n級臺階有多少種解法,只需要知道跳n-1級臺階和跳n-2級臺階的跳法,把他們加起來就可以。即得到一個公式f(n)=f(n-1)+f(n-2)。

常規解法(遞歸)

看到這個式子f(n)=f(n-1)+f(n-2),應該很快能反應:斐波那契亞數列,代碼很容易寫出來。遞歸的關鍵是確認遞歸出口,即:當只有1級臺階,只有一種跳法;只有2級臺階時,有兩種跳法。

代碼如下:

function frogJump(n) {
if (n >= 3) {
let result = frogJump(n - 1) + frogJump(n - 2)
return result
} else if (n === 1) {
return 1
}else if(n===2) {
return 2
}
}
let result = frogJump(6) // 13
console.log(result)

復雜度分析

上面這張遞歸解法只有60分,因為時間復雜度太高。

圖片

可以看到,因為沒有把結果保存,出現了很多重復計算的步驟:為了得到f(6)的結果,需要計算f(5)和f(4),為了得到f(5)的結果,需要計算f(4)和f(3),這里兩次計算f(4)是獨立的事件,也就是說,我們做了很多重復工作。

把上面這棵樹補充成一個完全樹,如下:

圖片

這種算法復雜度可以用2^0+2^1+2^2+...+2^4表示,即時間復雜度近似為O(2^N)(回憶一下高中數學的等比數列)。

而空間復雜度是調用棧的深度,從上面的圖可以看出來,最大的棧深是n-1,即空間復雜度是O(n)

進階解法(尾遞歸)

上面這種解法時間復雜度很高在于做了很多重復計算,從遞歸公式能看出來:f(n)=f(n-1)+f(n-2)=f(n-2)+f(n-3)+f(n-3)+f(n-4),一生二,二生四,四生八,整個計算過程就像是發散開來一樣。每一次調用都沒有保留下“狀態”,造成了大量的計算浪費。

只要我們保留下計算的結果,就可以把時間復雜度控制在O(n),也就是下面“尾遞歸”。

代碼如下:

function frogJump(first, second, n) {
let a = first,
b = second
let c = first + second
if (n > 3) {
a = second
b = first + second
return frogJump(a, b, n - 1)
} else if (n === 3) {
return c
} else if ( n === 2) {
return 2
} else if(n===1) {
return 1
}
}
let result = frogJump(1, 2, 6)
console.log(result)

我們用abc三個變量,把計算的結果保存下來,避免重復的工作。從first=1,second=2開始計算,每次遞歸調用更新first和second的值,這就是在保存下每次計算的結果,供下一次遞歸使用。直到n=3,滿足遞歸終止條件。

復雜度分析

這種尾遞歸,時間復雜度只有O(N),但他是幾種解法里面最難想到,也最難理解的。空間復雜度即遞歸的深度,是O(N)。

進階解法(循環)

循環和遞歸是可以相互轉化的,所以一種優化思路是用循環把上面的邏輯實現。

function frogJump(n) {
if (n === 1) {
return 1
} else if(n===2) {
return 2
}else {
let a = 1,
b = 2,
c
let count = 0
while (count < n - 2) {
c = a + b
a = b
b = c
count++
}
return c
}
}
let result = frogJump(6)
console.log(result)

我們首先知道了計算公式f(n)=f(n-1)+f(n-2);并且知道:當只有一級臺階時,只有一種解法,只有兩級臺階時,只有兩種解法。如果有三級臺階,計算一次即可(計算F(3));有四級臺階,計算兩次即可(計算f(3)、f(4))所以可推,當計算f(n)時,需要計算的次數是n-2,這就是循環的次數。上面的代碼便不難寫出。

復雜度分析

通過循環,我們同樣保留下了計算的結果,減少了重復的工作,時間復雜度是O(N)。空間復雜度是O(1)。

結語

通過這道算法題,能感受到循環通常比遞歸在時間復雜度上有優勢,但它更難想到,代碼塊也會更復雜。通常一個算法的遞歸和循環是可以相互轉化的,可以試著把之前刷過的題用不同的思路實現一下。

責任編輯:姜華 來源: 前端私教年年
相關推薦

2021-04-29 07:15:20

動態規劃DP

2024-04-25 08:33:25

算法時間復雜度空間復雜度

2021-04-14 14:50:27

計算機模型 技術

2015-10-13 09:43:43

復雜度核心

2020-12-30 09:20:27

代碼

2021-01-05 10:41:42

算法時間空間

2024-07-30 10:55:25

2009-07-09 10:45:16

C#基本概念復雜度遞歸與接口

2019-11-18 12:41:35

算法Python計算復雜性理論

2018-12-18 10:11:37

軟件復雜度軟件系統軟件開發

2019-12-24 09:46:00

Linux設置密碼

2022-08-16 09:04:23

代碼圈圈復雜度節點

2020-02-06 13:59:48

javascript算法復雜度

2021-10-15 09:43:12

希爾排序復雜度

2021-09-17 10:44:50

算法復雜度空間

2022-08-25 11:00:19

編程系統

2021-06-28 06:15:14

算法Algorithm時間空間復雜度

2023-03-03 08:43:08

代碼重構系統

2021-10-13 06:49:15

時間復雜度快排

2020-06-01 08:42:11

JavaScript重構函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美三级免费观看 | 夜夜夜夜夜夜曰天天天 | 99re在线视频| 久久福利电影 | 偷拍自拍网站 | 久久99精品久久久久久国产越南 | 国产女人与拘做受免费视频 | 日本精品久久 | 精品国产一级 | 午夜免费视频 | 精品99在线 | 91精品国产日韩91久久久久久 | 97精品视频在线 | 日日做夜夜爽毛片麻豆 | 日韩在线欧美 | 一区二区三区精品视频 | 日韩成人影院 | av入口| 91免费看片 | 国精产品一区一区三区免费完 | 毛片区 | 欧美精品一区二区三区在线 | 美女视频久久 | 色久伊人 | 亚洲视频二 | 亚州成人| 日本黄色激情视频 | 涩涩视频网站在线观看 | 久久夜视频 | 亚洲高清网 | 国产成人综合亚洲欧美94在线 | 中文字幕第100页 | 久久av一区二区 | 午夜影院在线观看 | 色综合视频 | 欧美激情视频一区二区三区在线播放 | 精品久久一区 | 国产亚洲精品精品国产亚洲综合 | 天天干天天干 | 免费在线观看成年人视频 | 中文在线一区 |