Python演算法:如何解決樓梯臺階問題
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
讓我們考慮以下問題。
有一個有N個臺階的樓梯,你一次可以爬1或2個臺階。
給定N,編寫一個函式,返回爬完樓梯的方式數量。步驟的順序很重要。
例如,如果N是4,那麼有5種方式:
- 1,1,1,1
- 2,1,1
- 1,2,1
- 1,1,2
- 2,2
如果規定的不是一次只能爬1或2步,而是可以使用正整數X集合內的任意數字爬樓梯,那會怎麼樣?例如,如果X = {1,3,5},則表示一次爬升1,3或5階樓梯。
解決方案
從一些測試案例開始總是好的做法。讓我們從小的案例開始,看看能否找到某種規律。
- N = 1,1種爬樓方式:[1]
- N = 2,2種爬樓方式:[1,1],[2]
- N = 3,3種爬樓方式:[1,2],[1,1,1],[2,1]
- N = 4,5種爬樓方式:[1,1,2],[2,2],[1,2,1],[1,1,1,1],[2,1,1]
你有沒有注意到什麼?請看N = 3時,爬完3階樓梯的方法數量是3,基於N = 1和N = 2。存在什麼關係?
爬完N = 3的兩種方法是首先達到N = 1,然後再往上爬2步,或達到N = 2再向上爬1步。所以 f(3) = f(2) + f(1)。
這對N = 4是否成立呢?是的,這也是成立的。因為我們只能在達到第三個臺階然後再爬一步,或者在到了第二個臺階之後再爬兩步這兩種方式爬完4個臺階。所以f(4) = f(3) + f(2)。
所以關係如下: f(n) = f(n – 1) + f(n – 2),且f(1) = 1和f(2) = 2。這就是斐波那契數列。
def fibonacci(n): if n <= 1: return 1 return fibonacci(n - 1) + fibonacci(n - 2)
當然,這很慢(O(2^N))——我們要做很多重複的計算!通過迭代計算,我們可以更快:
def fibonacci(n): a, b = 1, 2 for _ in range(n - 1): a, b = b, a + b return a
現在,讓我們嘗試概括我們學到的東西,看看是否可以應用到從集合X中取步數這個要求下的爬樓梯。類似的推理告訴我們,如果X = {1,3,5},那麼我們的演算法應該是f(n) = f(n – 1) + f(n – 3) + f(n – 5)。如果n <0,那麼我們應該返回0,因為我們不能爬負數。
def staircase(n, X): if n < 0: return 0 elif n == 0: return 1 elif n in X: return 1 + sum(staircase(n - x, X) for x in X if x < n) else: return sum(staircase(n - x, X) for x in X if x < n)
這也很慢(O(|X|^N)),因為也重複計算了。我們可以使用動態程式設計來加快速度。
每次的輸入cache[i]
將包含我們可以用集合X
到達臺階i
的方法的數量。然後,我們將使用與之前相同的遞迴從零開始構建陣列:
def staircase(n, X): cache = [0 for _ in range(n + 1)] cache[0] = 1 for i in range(n + 1): cache[i] += sum(cache[i - x] for x in X if i - x > 0) cache[i] += 1 if i in X else 0 return cache[-1]
現在時間複雜度為O(N * |X|),空間複雜度為O(N)。
歡迎繼續探索其他有趣的程式設計問題。
譯文連結:http://www.codeceo.com/article/python-staircase-problem.html
英文原文:How to Solve the Staircase Problem
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- 使用 JavaScript 解決經典爬樓梯問題JavaScript
- [演算法] 一、爬樓梯演算法
- Python演算法:如何解決迴文索引問題Python演算法索引
- [Python手撕]爬樓梯Python
- LeetCode 70題 爬樓梯 -- JavaScriptLeetCodeJavaScript
- 我用演算法學golang(爬樓梯)演算法Golang
- 樓梯有n個臺階,上樓可以一步上1階,也可以一步上兩階。一共有多少種上樓的方法?
- 不管是青蛙跳臺階還是who爬樓梯,能上去就行
- LeetCode每日一題:爬樓梯(No.70)LeetCode每日一題
- [Python手撕]使用最小花費爬樓梯Python
- 70. 爬樓梯
- leetcode 70 爬樓梯LeetCode
- 階梯訪問表優化優化
- 讓我們一起啃演算法----爬樓梯演算法
- 超級樓梯 hd 2041
- 增補部落格 第十九篇 python 爬樓梯Python
- 跨域問題?如何解決?跨域
- 如何解決python 圖表中文顯示亂碼問題Python
- 力扣---70. 爬樓梯力扣
- hdu.2042 超級樓梯
- 覆盤 PHP 經典面試問題解決過程:上臺階問題PHP面試
- (39/60)DP基礎、斐波那契數、爬樓梯、用最小花費爬樓梯
- 如何解決 github 訪問慢的問題Github
- 如何解決app閃退問題APP
- 如何解決TOP-K問題
- 前端跨域問題如何解決前端跨域
- 如何解決MRAM壽命問題
- 如何解決快取失效問題快取
- JavaScript原生實現樓梯外掛JavaScript
- 教你如何解決Python模組導包沒有找到的問題Python
- 如何解決sms-activate的解決問題
- 如何解決0.1 +0.2===0.30000000000000004類問題
- 如何解決Facebook SDK常見問題?
- 如何解決MES交付困難問題?
- 日期型別有問題,如何解決?型別
- 如何解決資料庫配置問題資料庫
- 頭疼,大事務問題如何解決?
- Spark任務OOM問題如何解決?SparkOOM