comments | difficulty | edit_url |
---|---|---|
true |
简单 |
三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
示例1:
输入:n = 3 输出:4 说明: 有四种走法
示例2:
输入:n = 5 输出:13
提示:
- n范围在[1, 1000000]之间
我们定义
递推公式为
由于
时间复杂度
class Solution:
def waysToStep(self, n: int) -> int:
a, b, c = 1, 2, 4
mod = 10**9 + 7
for _ in range(n - 1):
a, b, c = b, c, (a + b + c) % mod
return a
class Solution {
public int waysToStep(int n) {
final int mod = (int) 1e9 + 7;
int a = 1, b = 2, c = 4;
for (int i = 1; i < n; ++i) {
int t = a;
a = b;
b = c;
c = (((a + b) % mod) + t) % mod;
}
return a;
}
}
class Solution {
public:
int waysToStep(int n) {
const int mod = 1e9 + 7;
int a = 1, b = 2, c = 4;
for (int i = 1; i < n; ++i) {
int t = a;
a = b;
b = c;
c = (((a + b) % mod) + t) % mod;
}
return a;
}
};
func waysToStep(n int) int {
const mod int = 1e9 + 7
a, b, c := 1, 2, 4
for i := 1; i < n; i++ {
a, b, c = b, c, (a+b+c)%mod
}
return a
}
impl Solution {
pub fn ways_to_step(n: i32) -> i32 {
let (mut a, mut b, mut c) = (1, 2, 4);
let m = 1000000007;
for _ in 1..n {
let t = a;
a = b;
b = c;
c = (((a + b) % m) + t) % m;
}
a
}
}
/**
* @param {number} n
* @return {number}
*/
var waysToStep = function (n) {
let [a, b, c] = [1, 2, 4];
const mod = 1e9 + 7;
for (let i = 1; i < n; ++i) {
[a, b, c] = [b, c, (a + b + c) % mod];
}
return a;
};
int waysToStep(int n) {
const int mod = 1e9 + 7;
int a = 1, b = 2, c = 4;
for (int i = 1; i < n; ++i) {
int t = a;
a = b;
b = c;
c = (((a + b) % mod) + t) % mod;
}
return a;
}
class Solution {
func waysToStep(_ n: Int) -> Int {
let mod = Int(1e9) + 7
var a = 1, b = 2, c = 4
if n == 1 { return a }
if n == 2 { return b }
if n == 3 { return c }
for _ in 1..<n {
let t = a
a = b
b = c
c = ((a + b) % mod + t) % mod
}
return a
}
}
我们设
我们希望根据 $F(n-1) = \begin{bmatrix} F_{n - 2} & F_{n - 3} & F_{n - 4} \end{bmatrix}$ 推出
由于
我们定义初始矩阵 $res = \begin{bmatrix} 1 & 1 & 0 \end{bmatrix}$,那么
时间复杂度
import numpy as np
class Solution:
def waysToStep(self, n: int) -> int:
if n < 4:
return 2 ** (n - 1)
mod = 10**9 + 7
factor = np.asmatrix([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O"))
res = np.asmatrix([(4, 2, 1)], np.dtype("O"))
n -= 4
while n:
if n & 1:
res = res * factor % mod
factor = factor * factor % mod
n >>= 1
return res.sum() % mod
class Solution {
private final int mod = (int) 1e9 + 7;
public int waysToStep(int n) {
if (n < 4) {
return (int) Math.pow(2, n - 1);
}
long[][] a = {{1, 1, 0}, {1, 0, 1}, {1, 0, 0}};
long[][] res = pow(a, n - 4);
long ans = 0;
for (long x : res[0]) {
ans = (ans + x) % mod;
}
return (int) ans;
}
private long[][] mul(long[][] a, long[][] b) {
int m = a.length, n = b[0].length;
long[][] c = new long[m][n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < b.length; ++k) {
c[i][j] = (c[i][j] + a[i][k] * b[k][j] % mod) % mod;
}
}
}
return c;
}
private long[][] pow(long[][] a, int n) {
long[][] res = {{4, 2, 1}};
while (n > 0) {
if ((n & 1) == 1) {
res = mul(res, a);
}
a = mul(a, a);
n >>= 1;
}
return res;
}
}
class Solution {
public:
int waysToStep(int n) {
if (n < 4) {
return pow(2, n - 1);
}
vector<vector<ll>> a = {{1, 1, 0}, {1, 0, 1}, {1, 0, 0}};
vector<vector<ll>> res = qpow(a, n - 4);
ll ans = 0;
for (ll x : res[0]) {
ans = (ans + x) % mod;
}
return ans;
}
private:
using ll = long long;
const int mod = 1e9 + 7;
vector<vector<ll>> mul(vector<vector<ll>>& a, vector<vector<ll>>& b) {
int m = a.size(), n = b[0].size();
vector<vector<ll>> c(m, vector<ll>(n));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < b.size(); ++k) {
c[i][j] = (c[i][j] + a[i][k] * b[k][j] % mod) % mod;
}
}
}
return c;
}
vector<vector<ll>> qpow(vector<vector<ll>>& a, int n) {
vector<vector<ll>> res = {{4, 2, 1}};
while (n) {
if (n & 1) {
res = mul(res, a);
}
a = mul(a, a);
n >>= 1;
}
return res;
}
};
const mod = 1e9 + 7
func waysToStep(n int) (ans int) {
if n < 4 {
return int(math.Pow(2, float64(n-1)))
}
a := [][]int{{1, 1, 0}, {1, 0, 1}, {1, 0, 0}}
res := pow(a, n-4)
for _, x := range res[0] {
ans = (ans + x) % mod
}
return
}
func mul(a, b [][]int) [][]int {
m, n := len(a), len(b[0])
c := make([][]int, m)
for i := range c {
c[i] = make([]int, n)
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
for k := 0; k < len(b); k++ {
c[i][j] = (c[i][j] + a[i][k]*b[k][j]%mod) % mod
}
}
}
return c
}
func pow(a [][]int, n int) [][]int {
res := [][]int{{4, 2, 1}}
for n > 0 {
if n&1 == 1 {
res = mul(res, a)
}
a = mul(a, a)
n >>= 1
}
return res
}
/**
* @param {number} n
* @return {number}
*/
const mod = 1e9 + 7;
var waysToStep = function (n) {
if (n < 4) {
return Math.pow(2, n - 1);
}
const a = [
[1, 1, 0],
[1, 0, 1],
[1, 0, 0],
];
let ans = 0;
const res = pow(a, n - 4);
for (const x of res[0]) {
ans = (ans + x) % mod;
}
return ans;
};
function mul(a, b) {
const [m, n] = [a.length, b[0].length];
const c = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
for (let k = 0; k < b.length; ++k) {
c[i][j] =
(c[i][j] + Number((BigInt(a[i][k]) * BigInt(b[k][j])) % BigInt(mod))) % mod;
}
}
}
return c;
}
function pow(a, n) {
let res = [[4, 2, 1]];
while (n) {
if (n & 1) {
res = mul(res, a);
}
a = mul(a, a);
n >>= 1;
}
return res;
}