算法--递归--走台阶问题(2种递归+递归改循环)
生活随笔
收集整理的這篇文章主要介紹了
算法--递归--走台阶问题(2种递归+递归改循环)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 遞歸:
- 注意事項:
- 問題1
- 思路
- 1.遞歸代碼(未考慮重復計算問題)
- 2.循環代碼
- 3.遞歸代碼(避免重復計算問題)
- 測試運行時間
- 問題2
遞歸:
一個問題可以分解成若干子問題,且求解思路一樣,當到一定的情況下有終止條件,這樣的問題可以用遞歸方法求解
注意事項:
問題1
給你 n 個臺階,你的最大步幅是2步,可以一次走1步,也可以一次走2步,問有多少種走法?
思路
1.遞歸代碼(未考慮重復計算問題)
以下所有代碼原來采用 size_t 溢出,改用 unsigned long
#include <iostream> using namespace std; unsigned long cal(unsigned long n) {if(n==1)return 1;else if(n==2)return 2;return cal(n-1)+cal(n-2); } int main() {size_t n;cout << "請輸入你要走的臺階數 n :" ;cin >> n;cout << "走臺階有 " << cal(n) << " 種方案。" << endl;return 0; }以上遞歸方法,在 n 比較小的時候運行時間較短
輸入 n = 100 時,超過10s還沒出結果,我就終止程序了。以下改用循環。
2.循環代碼
#include <iostream> using namespace std; int main() //循環 {unsigned long n, step, nextStep = 2, nextnextStep = 1;cout << "請輸入你要走的臺階數 n :" ;cin >> n;if(n > 0){if(n == 1){step = 1;} else if(n == 2){step = 2;}else{for(int i = 2; i < n; ++i){step = nextStep + nextnextStep;nextnextStep = nextStep;nextStep = step;}}cout << "走臺階有 " << step << " 種方案。" << endl;}return 0; }輸入 n = 100 時,改用循環,眨眼間出結果。
3.遞歸代碼(避免重復計算問題)
代碼 1 中的 f(n), 比如 n = 5 時
以下代碼,屏蔽多次計算重復的值
輸入 n = 100,程序也是眨眼間出結果
測試運行時間
測試程序運行時間shell代碼:https://blog.csdn.net/qq_21201267/article/details/81840299
問題2
給你 n 個臺階,你的最大步幅是2步,可以一次走1步,也可以一次走2步,先邁左腳,要求最后到達時是右腳,問有多少種走法?
解法1:模擬實際的行走,暴力搜索
/**1. @description: 39個臺階,一次走1步或2步,左腳出發,要求右腳到達2. @author: michael ming3. @date: 2019/4/6 18:174. @modified by: */ #include <iostream> using namespace std; void recursion(const unsigned long &targetStairs, unsigned long steps, unsigned long stairsWalkAway, unsigned long &ways) { //暴力搜索,n很大時效果不好if(stairsWalkAway > targetStairs) //走過了,不做記錄return;else if(stairsWalkAway == targetStairs && steps%2 == 0) //正好走到,且步數為偶數(右腳到達){ways++; //記錄一種方案可以return;}else //沒走到,繼續遞歸{recursion(targetStairs, steps+1, stairsWalkAway+1, ways);recursion(targetStairs, steps+1, stairsWalkAway+2, ways);} } int main() {unsigned long stairs = 0, steps = 0, stairsWalkAway = 0, ways = 0;cout << "請輸入臺階個數:" << endl;cin >> stairs;recursion(stairs, steps, stairsWalkAway, ways);cout << "左腳出發,右腳到達的方案有:" << ways << " 種。" << endl;return 0; }解法2:遞推公式和之前一樣,結束條件變了
解法3:動態規劃,現在還不太明白
見他人博客:
https://blog.csdn.net/qq_40269087/article/details/80236102
大概的思路是:自底向上
- 用 left [ i ] 表示剩余 i 個臺階,左腳到達的可能方案, right [ i ] 表示右腳到達的方案
- 邊界條件: left [ 1 ] = 1; left [ 2 ] = 1; right [ 1 ] = 0; right [ 2 ] = 1
- 現在還有3個臺階到達,相當于在前面到達的方案中,退一步(1個臺階或者2個臺階),那么我在剩余3個臺階時,左腳到達 left [ 3 ] = right [ 2 ] + right [ 1 ] ;(右腳可以到達的方案,后退一步就變成了左腳到達的方案)
- 同理 right [ 3 ] = left [ 2 ] + left [ 1 ]
總結
以上是生活随笔為你收集整理的算法--递归--走台阶问题(2种递归+递归改循环)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 230. 二叉搜索树中
- 下一篇: 数据结构--链表--约瑟夫环问题(单向循