Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f338f95

Browse files
feat: add solutions to lc problem: No.0070 (#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)

AltStyle によって変換されたページ (->オリジナル) /