您的位置:首页 > 大数据 > 人工智能

LeetCode 70. Climbing Stairs(爬梯子)

2018-03-25 18:33 501 查看
题目描述:
    You are climbing a stair case. It takes n steps to reach to the top.
    Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
    Note: Given n will be a positive integer.例子一:Input: 2
Output: 2
Explanation: There are two ways to climb to the top.

1. 1 step + 1 step
2. 2 steps例子二:Input: 3
Output: 3
Explanation: There are three ways to climb to the top.

1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step分析:
    题意:一个梯子,走n步可以到达顶点,每次只能走1步或者2步,返回所有到达顶点的不同方式。
    思路:这道题可以采用数学递推公式计算,还可以采用快速矩阵幂进行优化。我们分别展开分析。
    ① 数学递推公式:假设爬到梯子的第i层有F(i)种,那么它有两种情况:Ⅰ. 从梯子第(i - 1)层,走1步到达第i层,这里有F(i - 1)种;Ⅱ. 从梯子第(i - 2)层,走2步到达第i层,这里有F(i - 2)种。那递推公式为F(i) = F(i - 1) + F(i - 2),其中F(0) = 1,F(1) = 1。我们套用公式直接计算即可。
    时间复杂度为O(n)。
    ② 快速矩阵幂:这道题是LeetCode 50的进化版本,因为快速矩阵幂是快速幂运算的一个变种,总体运算思想不变,只是从xⁿ(数字)转化为Aⁿ(矩阵)。我们把数学递推式转化为矩阵运算的格式,得到矩阵递推公式,这里还给出最终计算F(n)的两种方法,没有本质区别,不影响时间复杂度,代码当中采用了第二种技巧。具体过程如下图所示。



    时间复杂度为O(log(n))。
代码(数学递推式):
#include <bits/stdc++.h>

using namespace std;

// a0 = 1, a1 = 1, a(n) = a(n - 1) + a(n - 2), n >= 2
class Solution {
public:
int climbStairs(int n) {
// Exceptional Case:
if(n <= 2){
return n;
}
int a0 = 1, a1 = 1;
for(int i = 2; i <= n; i++){
int tmp = a1;
a1 += a0;
a0 = tmp;
}
return a1;
}
};代码(快速矩阵幂):
#include <bits/stdc++.h>

using namespace std;

// Fast Matrix Power

typedef vector<int> vec;
typedef vector<vec> mat;

// calculate mat(A) * mat(B)
mat mul(mat &A, mat &B){
mat C(A.size(), vec(B[0].size(), 0));
for(int i = 0; i <= A.size() - 1; i++){
for(int j = 0; j <= B[0].size() - 1; j++){
for(int k = 0; k <= B.size() - 1; k++){
C[i][j] += A[i][k] * B[k][j];
}
}
}
return C;
}

// calculate (mat(A)) ^ n
mat pow(mat A, int n){
mat B(A.size(), vec(A.size(), 0));
// init
for(int i = 0; i <= A.size() - 1; i++){
B[i][i] = 1;
}
while(n > 0){
if(n & 1){
B = mul(B, A);
}
A = mul(A, A);
n >>= 1;
}
return B;
}

class Solution {
public:
int climbStairs(int n) {
// Exceptional Case:
if(n <= 2){
return n;
}
mat A(2, vec(2, 0));
A[0][0] = 1;
A[0][1] = 1;
A[1][0] = 1;
A[1][1] = 0;
A = pow(A, n);
return A[0][0];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息