一個臺階總共有n 級,若是一次能夠跳1 級,也能夠跳2 級,求總共有多少種跳法。面試
這個題目常常出現,包括Microsoft 等比較重視算法的公司都曾前後選用過個這道題做爲面試題或者筆試題。算法
若是隻有1 級臺階,那顯然只有一種跳法;數組
若是有2 級臺階,那就有兩種跳的方法了:一種是分兩次跳,每次跳1 級;另一種就是一次跳2 級。優化
當臺階數>2 級時,第一次跳的時候就有兩種不一樣的選擇:一種是 第一次只跳1 級,此時跳法數目等於後面剩下的n-1 級臺階的跳法數目,即爲f(n-1);另一種選擇是第一次跳2 級,此時跳法數目等於後面剩下的n-2 級臺階的跳法數目,即爲f(n-2)。 因此,n 級臺階時的不一樣跳法的總數 f(n) = f(n-1) + f(n-2)。spa
/ 1 (n=1)
即:f(n) = 2 (n=2)
\ f(n-1) + (f-2) (n>2)code
其實,這就是Fibonacci 序列。算法複雜度爲:(O(n))。 blog
int Fibonacci1(unsigned int N) { if(N<=2) return N; int fibtwo=2; int fibone=1; int fibN=0; for(unsigned int i=3;i<=N;i++) { fibN=fibone+fibtwo; fibone=fibtwo; fibtwo=fibN; } return fibN; }
1 /** 2 * 爬樓梯問題: 實質就是斐波那契數列. 3 * 4 * @author X-knight 5 * 6 */ 7 public class ClimbTheStairs { 8 int total; 9 10 // 遞歸調用 11 public int fib01(int n) { 12 if (n == 1 || n == 2) 13 total = n; 14 else 15 total = fib01(n - 2) + fib01(n - 1); 16 return total; 17 } 18 19 // 三目運算符 20 public int fib02(int n) { 21 return (n == 1 || n == 2) ? n : fib02(n - 2) + fib02(n - 1); 22 } 23 24 // 備忘錄法 25 public int dfs(int n, int[] array) { 26 if (array[n] != 0) { 27 return array[n]; 28 } else { 29 array[n] = dfs(n - 1, array) + dfs(n - 2, array); 30 return array[n]; 31 } 32 } 33 34 public int fib03(int n) { 35 if (n == 0) { 36 return 1; 37 } 38 if (n == 1 || n == 2) { 39 return n; 40 } else { 41 int[] array = new int[n + 1]; 42 array[1] = 1; 43 array[2] = 2; 44 return dfs(n, array); 45 } 46 } 47 48 // 動態規劃法 (利用數組來存儲) 49 public int fib04(int n) { 50 if (n == 0) 51 return 1; 52 int[] array = new int[n + 1]; 53 array[0] = 1; 54 array[1] = 1; 55 for (int i = 2; i <= n; i++) { 56 array[i] = array[i - 1] + array[i - 2]; 57 } 58 return array[n]; 59 } 60 61 // 狀態壓縮法(又稱滾動數組、滑動窗口,用於優化動態規劃法的空間複雜度) 62 public int fib05(int n) { 63 if (n == 1 || n == 0) 64 return 1; 65 n = n - 1; 66 int result = 0; 67 int zero = 1; 68 int first = 1; 69 while (n > 0) { 70 result = zero + first; 71 zero = first; 72 first = result; 73 n--; 74 } 75 return result; 76 } 77 78 // 斐波那契數列的通項公式 79 public int fib06(int n) { 80 if (n == 0) 81 return 1; 82 if (n == 1 || n == 2) 83 return n; 84 int result = (int) Math.floor( 85 1 / Math.sqrt(5) * (Math.pow((1 + Math.sqrt(5)) / 2, n + 1) - Math.pow((1 - Math.sqrt(5)) / 2, n + 1))); 86 return result; 87 } 88 89 @Test 90 public void testClimb() { 91 int num01 = fib01(7); 92 System.out.println(num01); 93 int num02 = fib02(8); 94 System.out.println(num02); 95 int num03 = fib03(0); 96 System.out.println(num03); 97 int num04 = fib04(8); 98 System.out.println(num04); 99 int num05 = fib05(8); 100 System.out.println(num05); 101 int num06 = fib06(2); 102 System.out.println(num06); 103 } 104 }