Skip to content

Commit f338f95

Browse files
authored
feat: add solutions to lc problem: No.0070 (doocs#1608)
No.0070.Climbing Stairs
1 parent 93f9000 commit f338f95

File tree

2 files changed

+480
-16
lines changed

2 files changed

+480
-16
lines changed

solution/0000-0099/0070.Climbing Stairs/README.md

Lines changed: 260 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,46 @@ $$
6060

6161
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
6262

63+
**方法二:矩阵快速幂**
64+
65+
我们设 $Fib(n)$ 表示一个 $1 \times 2$ 的矩阵 $\begin{bmatrix} F_n & F_{n - 1} \end{bmatrix}$,其中 $F_n$ 和 $F_{n - 1}$ 分别是第 $n$ 个和第 $n - 1$ 个斐波那契数。
66+
67+
我们希望根据 $Fib(n-1) = \begin{bmatrix} F_{n - 1} & F_{n - 2} \end{bmatrix}$ 推出 $Fib(n)$。也即是说,我们需要一个矩阵 $base$,使得 $Fib(n - 1) \times base = Fib(n)$,即:
68+
69+
$$
70+
\begin{bmatrix}
71+
F_{n - 1} & F_{n - 2}
72+
\end{bmatrix} \times base = \begin{bmatrix} F_n & F_{n - 1} \end{bmatrix}
73+
$$
74+
75+
由于 $F_n = F_{n - 1} + F_{n - 2}$,所以矩阵 $base$ 的第一列为:
76+
77+
$$
78+
\begin{bmatrix}
79+
1 \\
80+
1
81+
\end{bmatrix}
82+
$$
83+
84+
第二列为:
85+
86+
$$
87+
\begin{bmatrix}
88+
1 \\
89+
0
90+
\end{bmatrix}
91+
$$
92+
93+
因此有:
94+
95+
$$
96+
\begin{bmatrix} F_{n - 1} & F_{n - 2} \end{bmatrix} \times \begin{bmatrix}1 & 1 \\ 1 & 0\end{bmatrix} = \begin{bmatrix} F_n & F_{n - 1} \end{bmatrix}
97+
$$
98+
99+
我们定义初始矩阵 $res = \begin{bmatrix} 1 & 1 \end{bmatrix}$,那么 $F_n$ 等于 $res$ 乘以 $base^{n - 1}$ 的结果矩阵中第一行的第一个元素。使用矩阵快速幂求解即可。
100+
101+
时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。
102+
63103
<!-- tabs:start -->
64104

65105
### **Python3**
@@ -75,6 +115,31 @@ class Solution:
75115
return b
76116
```
77117

118+
```python
119+
class Solution:
120+
def climbStairs(self, n: int) -> int:
121+
def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
122+
m, n = len(a), len(b[0])
123+
c = [[0] * n for _ in range(m)]
124+
for i in range(m):
125+
for j in range(n):
126+
for k in range(len(a[0])):
127+
c[i][j] = c[i][j] + a[i][k] * b[k][j]
128+
return c
129+
130+
def pow(a: List[List[int]], n: int) -> List[List[int]]:
131+
res = [[1, 1], [0, 0]]
132+
while n:
133+
if n & 1:
134+
res = mul(res, a)
135+
n >>= 1
136+
a = mul(a, a)
137+
return res
138+
139+
a = [[1, 1], [1, 0]]
140+
return pow(a, n - 1)[0][0]
141+
```
142+
78143
### **Java**
79144

80145
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -93,6 +158,40 @@ class Solution {
93158
}
94159
```
95160

161+
```java
162+
class Solution {
163+
public int climbStairs(int n) {
164+
int[][] a = {{1, 1,}, {1, 0}};
165+
return pow(a, n - 1)[0][0];
166+
}
167+
168+
private int[][] mul(int[][] a, int[][] b) {
169+
int m = a.length, n = b[0].length;
170+
int[][] c = new int[m][n];
171+
for (int i = 0; i < m; ++i) {
172+
for (int j = 0; j < n; ++j) {
173+
for (int k = 0; k < a[0].length; ++k) {
174+
c[i][j] += a[i][k] * b[k][j];
175+
}
176+
}
177+
}
178+
return c;
179+
}
180+
181+
private int[][] pow(int[][] a, int n) {
182+
int[][] res = {{1, 1}, {0, 0}};
183+
while (n > 0) {
184+
if ((n & 1) == 1) {
185+
res = mul(res, a);
186+
}
187+
n >>= 1;
188+
a = mul(a, a);
189+
}
190+
return res;
191+
}
192+
}
193+
```
194+
96195
### **C++**
97196

98197
```cpp
@@ -110,6 +209,87 @@ public:
110209
};
111210
```
112211
212+
```cpp
213+
class Solution {
214+
public:
215+
int climbStairs(int n) {
216+
vector<vector<long long>> a = {{1, 1}, {1, 0}};
217+
return pow(a, n - 1)[0][0];
218+
}
219+
220+
private:
221+
vector<vector<long long>> mul(vector<vector<long long>>& a, vector<vector<long long>>& b) {
222+
int m = a.size(), n = b[0].size();
223+
vector<vector<long long>> res(m, vector<long long>(n));
224+
for (int i = 0; i < m; ++i) {
225+
for (int j = 0; j < n; ++j) {
226+
for (int k = 0; k < a[0].size(); ++k) {
227+
res[i][j] += a[i][k] * b[k][j];
228+
}
229+
}
230+
}
231+
return res;
232+
}
233+
234+
vector<vector<long long>> pow(vector<vector<long long>>& a, int n) {
235+
vector<vector<long long>> res = {{1, 1}, {0, 0}};
236+
while (n) {
237+
if (n & 1) {
238+
res = mul(res, a);
239+
}
240+
a = mul(a, a);
241+
n >>= 1;
242+
}
243+
return res;
244+
}
245+
};
246+
```
247+
248+
### **Go**
249+
250+
```go
251+
func climbStairs(n int) int {
252+
a, b := 0, 1
253+
for i := 0; i < n; i++ {
254+
a, b = b, a+b
255+
}
256+
return b
257+
}
258+
```
259+
260+
```go
261+
type matrix [2][2]int
262+
263+
func climbStairs(n int) int {
264+
a := matrix{{1, 1}, {1, 0}}
265+
return pow(a, n-1)[0][0]
266+
}
267+
268+
func mul(a, b matrix) (c matrix) {
269+
m, n := len(a), len(b[0])
270+
for i := 0; i < m; i++ {
271+
for j := 0; j < n; j++ {
272+
for k := 0; k < len(a[0]); k++ {
273+
c[i][j] += a[i][k] * b[k][j]
274+
}
275+
}
276+
}
277+
return
278+
}
279+
280+
func pow(a matrix, n int) matrix {
281+
res := matrix{{1, 1}, {0, 0}}
282+
for n > 0 {
283+
if n&1 == 1 {
284+
res = mul(res, a)
285+
}
286+
a = mul(a, a)
287+
n >>= 1
288+
}
289+
return res
290+
}
291+
```
292+
113293
### **JavaScript**
114294

115295
```js
@@ -129,15 +309,47 @@ var climbStairs = function (n) {
129309
};
130310
```
131311

132-
### **Go**
312+
```js
313+
/**
314+
* @param {number} n
315+
* @return {number}
316+
*/
317+
var climbStairs = function (n) {
318+
const a = [
319+
[1, 1],
320+
[1, 0],
321+
];
322+
return pow(a, n - 1)[0][0];
323+
};
133324

134-
```go
135-
func climbStairs(n int) int {
136-
a, b := 0, 1
137-
for i := 0; i < n; i++ {
138-
a, b = b, a+b
139-
}
140-
return b
325+
function mul(a, b) {
326+
const [m, n] = [a.length, b[0].length];
327+
const c = Array(m)
328+
.fill(0)
329+
.map(() => Array(n).fill(0));
330+
for (let i = 0; i < m; ++i) {
331+
for (let j = 0; j < n; ++j) {
332+
for (let k = 0; k < a[0].length; ++k) {
333+
c[i][j] += a[i][k] * b[k][j];
334+
}
335+
}
336+
}
337+
return c;
338+
}
339+
340+
function pow(a, n) {
341+
let res = [
342+
[1, 1],
343+
[0, 0],
344+
];
345+
while (n) {
346+
if (n & 1) {
347+
res = mul(res, a);
348+
}
349+
a = mul(a, a);
350+
n >>= 1;
351+
}
352+
return res;
141353
}
142354
```
143355

@@ -154,6 +366,46 @@ function climbStairs(n: number): number {
154366
}
155367
```
156368

369+
```ts
370+
function climbStairs(n: number): number {
371+
const a = [
372+
[1, 1],
373+
[1, 0],
374+
];
375+
return pow(a, n - 1)[0][0];
376+
}
377+
378+
function mul(a: number[][], b: number[][]): number[][] {
379+
const [m, n] = [a.length, b[0].length];
380+
const c = Array(m)
381+
.fill(0)
382+
.map(() => Array(n).fill(0));
383+
for (let i = 0; i < m; ++i) {
384+
for (let j = 0; j < n; ++j) {
385+
for (let k = 0; k < a[0].length; ++k) {
386+
c[i][j] += a[i][k] * b[k][j];
387+
}
388+
}
389+
}
390+
return c;
391+
}
392+
393+
function pow(a: number[][], n: number): number[][] {
394+
let res = [
395+
[1, 1],
396+
[0, 0],
397+
];
398+
while (n) {
399+
if (n & 1) {
400+
res = mul(res, a);
401+
}
402+
a = mul(a, a);
403+
n >>= 1;
404+
}
405+
return res;
406+
}
407+
```
408+
157409
### **Rust**
158410

159411
```rust

0 commit comments

Comments
 (0)