diff --git a/lcci/08.01.Three Steps Problem/README.md b/lcci/08.01.Three Steps Problem/README.md index 421461ed9d774..93eacbfea15f8 100644 --- a/lcci/08.01.Three Steps Problem/README.md +++ b/lcci/08.01.Three Steps Problem/README.md @@ -19,7 +19,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.01.Three%20Steps%2
示例1:
- 输入:n = 3 + 输入:n = 3 输出:4 说明: 有四种走法@@ -226,37 +226,6 @@ $$ #### Python3 -```python -class Solution: - def waysToStep(self, n: int) -> int: - mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = (c[i][j] + a[i][k] * b[k][j] % mod) % mod - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[4, 2, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - - if n < 4: - return 2 ** (n - 1) - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 4)[0]) % mod -``` - -#### Python3 - ```python import numpy as np @@ -266,8 +235,8 @@ class Solution: if n < 4: return 2 ** (n - 1) mod = 10**9 + 7 - factor = np.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(4, 2, 1)], np.dtype("O")) + 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: diff --git a/lcci/08.01.Three Steps Problem/README_EN.md b/lcci/08.01.Three Steps Problem/README_EN.md index 93d93478b8bef..1f10f60a219b3 100644 --- a/lcci/08.01.Three Steps Problem/README_EN.md +++ b/lcci/08.01.Three Steps Problem/README_EN.md @@ -20,7 +20,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/08.01.Three%20Steps%2
- Input: n = 3 + Input: n = 3 Output: 4 @@ -229,37 +229,6 @@ The time complexity is $O(\log n)$, and the space complexity is $O(1)$. #### Python3 -```python -class Solution: - def waysToStep(self, n: int) -> int: - mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = (c[i][j] + a[i][k] * b[k][j] % mod) % mod - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[4, 2, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - - if n < 4: - return 2 ** (n - 1) - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 4)[0]) % mod -``` - -#### Python3 - ```python import numpy as np @@ -269,8 +238,8 @@ class Solution: if n < 4: return 2 ** (n - 1) mod = 10**9 + 7 - factor = np.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(4, 2, 1)], np.dtype("O")) + 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: diff --git a/lcci/08.01.Three Steps Problem/Solution2.py b/lcci/08.01.Three Steps Problem/Solution2.py index 47973c3c6b40d..ce8bd1b06daa3 100644 --- a/lcci/08.01.Three Steps Problem/Solution2.py +++ b/lcci/08.01.Three Steps Problem/Solution2.py @@ -1,26 +1,17 @@ -class Solution: - def waysToStep(self, n: int) -> int: - mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = (c[i][j] + a[i][k] * b[k][j] % mod) % mod - return c +import numpy as np - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[4, 2, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res +class Solution: + def waysToStep(self, n: int) -> int: if n < 4: return 2 ** (n - 1) - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 4)[0]) % mod + 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 diff --git a/lcci/08.01.Three Steps Problem/Solution3.py b/lcci/08.01.Three Steps Problem/Solution3.py deleted file mode 100644 index 7ee79117fbbaa..0000000000000 --- a/lcci/08.01.Three Steps Problem/Solution3.py +++ /dev/null @@ -1,17 +0,0 @@ -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.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(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 diff --git a/solution/0000-0099/0070.Climbing Stairs/README.md b/solution/0000-0099/0070.Climbing Stairs/README.md index e2c20cd366603..219e8ee1d35aa 100644 --- a/solution/0000-0099/0070.Climbing Stairs/README.md +++ b/solution/0000-0099/0070.Climbing Stairs/README.md @@ -252,28 +252,20 @@ $$ #### Python3 ```python +import numpy as np + + class Solution: def climbStairs(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - - a = [[1, 1], [1, 0]] - return pow(a, n - 1)[0][0] + res = np.asmatrix([(1, 1)], np.dtype("O")) + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res[0, 0] ``` #### Java @@ -478,33 +470,4 @@ function pow(a, n) { - - -### 方法三 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def climbStairs(self, n: int) -> int: - res = np.mat([(1, 1)], np.dtype("O")) - factor = np.mat([(1, 1), (1, 0)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res[0, 0] -``` - - - - - diff --git a/solution/0000-0099/0070.Climbing Stairs/README_EN.md b/solution/0000-0099/0070.Climbing Stairs/README_EN.md index 855bc87fbc9d9..5359c100e1ef2 100644 --- a/solution/0000-0099/0070.Climbing Stairs/README_EN.md +++ b/solution/0000-0099/0070.Climbing Stairs/README_EN.md @@ -251,28 +251,20 @@ The time complexity is $O(\log n)$, and the space complexity is $O(1)$. #### Python3 ```python +import numpy as np + + class Solution: def climbStairs(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - - a = [[1, 1], [1, 0]] - return pow(a, n - 1)[0][0] + res = np.asmatrix([(1, 1)], np.dtype("O")) + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res[0, 0] ``` #### Java @@ -477,33 +469,4 @@ function pow(a, n) { - - -### Solution 3 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def climbStairs(self, n: int) -> int: - res = np.mat([(1, 1)], np.dtype("O")) - factor = np.mat([(1, 1), (1, 0)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res[0, 0] -``` - - - - - diff --git a/solution/0000-0099/0070.Climbing Stairs/Solution2.py b/solution/0000-0099/0070.Climbing Stairs/Solution2.py index f38127ff7aee1..c843d038dd008 100644 --- a/solution/0000-0099/0070.Climbing Stairs/Solution2.py +++ b/solution/0000-0099/0070.Climbing Stairs/Solution2.py @@ -1,22 +1,14 @@ -class Solution: - def climbStairs(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c +import numpy as np - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - a = [[1, 1], [1, 0]] - return pow(a, n - 1)[0][0] +class Solution: + def climbStairs(self, n: int) -> int: + res = np.asmatrix([(1, 1)], np.dtype("O")) + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res[0, 0] diff --git a/solution/0000-0099/0070.Climbing Stairs/Solution3.py b/solution/0000-0099/0070.Climbing Stairs/Solution3.py deleted file mode 100644 index 073a590c5bccd..0000000000000 --- a/solution/0000-0099/0070.Climbing Stairs/Solution3.py +++ /dev/null @@ -1,14 +0,0 @@ -import numpy as np - - -class Solution: - def climbStairs(self, n: int) -> int: - res = np.mat([(1, 1)], np.dtype("O")) - factor = np.mat([(1, 1), (1, 0)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res[0, 0] diff --git a/solution/0500-0599/0509.Fibonacci Number/README.md b/solution/0500-0599/0509.Fibonacci Number/README.md index 55d97ea37ff03..29c2a0765103f 100644 --- a/solution/0500-0599/0509.Fibonacci Number/README.md +++ b/solution/0500-0599/0509.Fibonacci Number/README.md @@ -68,7 +68,15 @@ F(n) = F(n - 1) + F(n - 2),其中 n > 1 -### 方法一 +### 方法一:递推 + +我们定义两个变量 $a$ 和 $b$,初始时 $a = 0$, $b = 1$。 + +接下来,我们进行 $n$ 次循环,每次循环中,我们将 $a$ 和 $b$ 的值分别更新为 $b$ 和 $a + b$。 + +最后,返回 $a$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 为题目给定的整数 $n$。空间复杂度 $O(1)$。 @@ -132,9 +140,8 @@ func fib(n int) int { ```ts function fib(n: number): number { - let a = 0; - let b = 1; - for (let i = 0; i < n; i++) { + let [a, b] = [0, 1]; + while (n--) { [a, b] = [b, a + b]; } return a; @@ -166,12 +173,9 @@ impl Solution { * @return {number} */ var fib = function (n) { - let a = 0; - let b = 1; + let [a, b] = [0, 1]; while (n--) { - const c = a + b; - a = b; - b = c; + [a, b] = [b, a + b]; } return a; }; @@ -186,14 +190,14 @@ class Solution { * @return Integer */ function fib($n) { - if ($n == 0 || $n == 1) { - return $n; - } - $dp = [0, 1]; - for ($i = 2; $i <= $n; $i++) { - $dp[$i] = $dp[$i - 2] + $dp[$i - 1]; + $a = 0; + $b = 1; + for ($i = 0; $i < $n; $i++) { + $temp = $a; + $a = $b; + $b = $temp + $b; } - return $dp[$n]; + return $a; } } ``` @@ -204,18 +208,210 @@ class Solution { -### 方法二 +### 方法二:矩阵快速幂加速递推 + +我们设 $\textit{Fib}(n)$ 表示一个 $1 \times 2$ 的矩阵 $\begin{bmatrix} F_n & F_{n - 1} \end{bmatrix}$,其中 $F_n$ 和 $F_{n - 1}$ 分别是第 $n$ 个和第 $n - 1$ 个斐波那契数。 + +我们希望根据 $\textit{Fib}(n - 1) = \begin{bmatrix} F_{n - 1} & F_{n - 2} \end{bmatrix}$ 推出 $\textit{Fib}(n)$。也即是说,我们需要一个矩阵 $\textit{base}$,使得 $\textit{Fib}(n - 1) \times \textit{base} = \textit{Fib}(n)$,即: + +$$ +\begin{bmatrix} +F_{n - 1} & F_{n - 2} +\end{bmatrix} \times \textit{base} = \begin{bmatrix} F_n & F_{n - 1} \end{bmatrix} +$$ + +由于 $F_n = F_{n - 1} + F_{n - 2}$,所以矩阵 $\textit{base}$ 的第一列为: + +$$ +\begin{bmatrix} +1 \\ +1 +\end{bmatrix} +$$ + +第二列为: + +$$ +\begin{bmatrix} +1 \\ +0 +\end{bmatrix} +$$ + +因此有: + +$$ +\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} +$$ + +我们定义初始矩阵 $res = \begin{bmatrix} 1 & 0 \end{bmatrix}$,那么 $F_n$ 等于 $res$ 乘以 $\textit{base}^{n}$ 的结果矩阵中第一行的第二个元素。使用矩阵快速幂求解即可。 + +时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。 +#### Python3 + +```python +import numpy as np + + +class Solution: + def fib(self, n: int) -> int: + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + res = np.asmatrix([(1, 0)], np.dtype("O")) + while n: + if n & 1: + res = res * factor + factor = factor * factor + n >>= 1 + return res[0, 1] +``` + +#### Java + +```java +class Solution { + public int fib(int n) { + int[][] a = {{1, 1}, {1, 0}}; + return pow(a, n)[0][1]; + } + + private int[][] mul(int[][] a, int[][] b) { + int m = a.length, n = b[0].length; + int[][] c = new int[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]; + } + } + } + return c; + } + + private int[][] pow(int[][] a, int n) { + int[][] res = {{1, 0}}; + while (n > 0) { + if ((n & 1) == 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int fib(int n) { + vector> a = {{1, 1}, {1, 0}}; + return qpow(a, n)[0][1]; + } + + vector > mul(vector >& a, vector >& b) { + int m = a.size(), n = b[0].size(); + vector > c(m, vector (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]; + } + } + } + return c; + } + + vector > qpow(vector >& a, int n) { + vector > res = {{1, 0}}; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +}; +``` + +#### Go + +```go +func fib(n int) int { + a := [][]int{{1, 1}, {1, 0}} + return pow(a, n)[0][1] +} + +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] + } + } + } + return c +} + +func pow(a [][]int, n int) [][]int { + res := [][]int{{1, 0}} + for n > 0 { + if n&1 == 1 { + res = mul(res, a) + } + a = mul(a, a) + n >>= 1 + } + return res +} +``` + #### TypeScript ```ts function fib(n: number): number { - if (n < 2) { - return n; + const a: number[][] = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +} + +function mul(a: number[][], b: number[][]): number[][] { + 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] += a[i][k] * b[k][j]; + } + } } - return fib(n - 1) + fib(n - 2); + return c; +} + +function pow(a: number[][], n: number): number[][] { + let res = [[1, 0]]; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; } ``` @@ -224,11 +420,82 @@ function fib(n: number): number { ```rust impl Solution { pub fn fib(n: i32) -> i32 { - if n < 2 { - return n; + let a = vec![vec![1, 1], vec![1, 0]]; + pow(a, n as usize)[0][1] + } +} + +fn mul(a: Vec >, b: Vec >) -> Vec > { + let m = a.len(); + let n = b[0].len(); + let mut c = vec![vec![0; n]; m]; + + for i in 0..m { + for j in 0..n { + for k in 0..b.len() { + c[i][j] += a[i][k] * b[k][j]; + } + } + } + c +} + +fn pow(mut a: Vec >, mut n: usize) -> Vec > { + let mut res = vec![vec![1, 0], vec![0, 1]]; + + while n > 0 { + if n & 1 == 1 { + res = mul(res, a.clone()); + } + a = mul(a.clone(), a); + n >>= 1; + } + res +} +``` + +#### JavaScript + +```js +/** + * @param {number} n + * @return {number} + */ +var fib = function (n) { + const a = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +}; + +function mul(a, b) { + const m = a.length, + n = b[0].length; + const c = Array.from({ length: m }, () => Array(n).fill(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] += a[i][k] * b[k][j]; + } + } + } + return c; +} + +function pow(a, n) { + let res = [ + [1, 0], + [0, 1], + ]; + while (n > 0) { + if (n & 1) { + res = mul(res, a); } - Self::fib(n - 1) + Self::fib(n - 2) + a = mul(a, a); + n >>= 1; } + return res; } ``` diff --git a/solution/0500-0599/0509.Fibonacci Number/README_EN.md b/solution/0500-0599/0509.Fibonacci Number/README_EN.md index a9f6ba3b33252..f7ea5a5e7a518 100644 --- a/solution/0500-0599/0509.Fibonacci Number/README_EN.md +++ b/solution/0500-0599/0509.Fibonacci Number/README_EN.md @@ -66,7 +66,15 @@ F(n) = F(n - 1) + F(n - 2), for n > 1. -### Solution 1 +### Solution 1: Recurrence + +We define two variables $a$ and $b$, initially $a = 0$ and $b = 1$. + +Next, we perform $n$ iterations. In each iteration, we update the values of $a$ and $b$ to $b$ and $a + b$, respectively. + +Finally, we return $a$. + +The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$. @@ -130,9 +138,8 @@ func fib(n int) int { ```ts function fib(n: number): number { - let a = 0; - let b = 1; - for (let i = 0; i < n; i++) { + let [a, b] = [0, 1]; + while (n--) { [a, b] = [b, a + b]; } return a; @@ -164,12 +171,9 @@ impl Solution { * @return {number} */ var fib = function (n) { - let a = 0; - let b = 1; + let [a, b] = [0, 1]; while (n--) { - const c = a + b; - a = b; - b = c; + [a, b] = [b, a + b]; } return a; }; @@ -184,14 +188,14 @@ class Solution { * @return Integer */ function fib($n) { - if ($n == 0 || $n == 1) { - return $n; - } - $dp = [0, 1]; - for ($i = 2; $i <= $n; $i++) { - $dp[$i] = $dp[$i - 2] + $dp[$i - 1]; + $a = 0; + $b = 1; + for ($i = 0; $i < $n; $i++) { + $temp = $a; + $a = $b; + $b = $temp + $b; } - return $dp[$n]; + return $a; } } ``` @@ -202,18 +206,210 @@ class Solution { -### Solution 2 +### Solution 2: Matrix Exponentiation + +We define $\textit{Fib}(n)$ as a $1 \times 2$ matrix $\begin{bmatrix} F_n & F_{n - 1} \end{bmatrix}$, where $F_n$ and $F_{n - 1}$ are the $n$-th and $(n - 1)$-th Fibonacci numbers, respectively. + +We want to derive $\textit{Fib}(n)$ from $\textit{Fib}(n - 1) = \begin{bmatrix} F_{n - 1} & F_{n - 2} \end{bmatrix}$. In other words, we need a matrix $\textit{base}$ such that $\textit{Fib}(n - 1) \times \textit{base} = \textit{Fib}(n)$, i.e.: + +$$ +\begin{bmatrix} +F_{n - 1} & F_{n - 2} +\end{bmatrix} \times \textit{base} = \begin{bmatrix} F_n & F_{n - 1} \end{bmatrix} +$$ + +Since $F_n = F_{n - 1} + F_{n - 2}$, the first column of the matrix $\textit{base}$ is: + +$$ +\begin{bmatrix} +1 \\ +1 +\end{bmatrix} +$$ + +The second column is: + +$$ +\begin{bmatrix} +1 \\ +0 +\end{bmatrix} +$$ + +Thus, we have: + +$$ +\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} +$$ + +We define the initial matrix $res = \begin{bmatrix} 1 & 0 \end{bmatrix}$, then $F_n$ is equal to the second element of the first row of the result matrix obtained by multiplying $res$ with $\textit{base}^{n}$. We can solve this using matrix exponentiation. + +The time complexity is $O(\log n)$, and the space complexity is $O(1)$. +#### Python3 + +```python +import numpy as np + + +class Solution: + def fib(self, n: int) -> int: + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + res = np.asmatrix([(1, 0)], np.dtype("O")) + while n: + if n & 1: + res = res * factor + factor = factor * factor + n >>= 1 + return res[0, 1] +``` + +#### Java + +```java +class Solution { + public int fib(int n) { + int[][] a = {{1, 1}, {1, 0}}; + return pow(a, n)[0][1]; + } + + private int[][] mul(int[][] a, int[][] b) { + int m = a.length, n = b[0].length; + int[][] c = new int[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]; + } + } + } + return c; + } + + private int[][] pow(int[][] a, int n) { + int[][] res = {{1, 0}}; + while (n > 0) { + if ((n & 1) == 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int fib(int n) { + vector > a = {{1, 1}, {1, 0}}; + return qpow(a, n)[0][1]; + } + + vector > mul(vector >& a, vector >& b) { + int m = a.size(), n = b[0].size(); + vector > c(m, vector (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]; + } + } + } + return c; + } + + vector > qpow(vector >& a, int n) { + vector > res = {{1, 0}}; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +}; +``` + +#### Go + +```go +func fib(n int) int { + a := [][]int{{1, 1}, {1, 0}} + return pow(a, n)[0][1] +} + +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] + } + } + } + return c +} + +func pow(a [][]int, n int) [][]int { + res := [][]int{{1, 0}} + for n > 0 { + if n&1 == 1 { + res = mul(res, a) + } + a = mul(a, a) + n >>= 1 + } + return res +} +``` + #### TypeScript ```ts function fib(n: number): number { - if (n < 2) { - return n; + const a: number[][] = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +} + +function mul(a: number[][], b: number[][]): number[][] { + 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] += a[i][k] * b[k][j]; + } + } } - return fib(n - 1) + fib(n - 2); + return c; +} + +function pow(a: number[][], n: number): number[][] { + let res = [[1, 0]]; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; } ``` @@ -222,11 +418,82 @@ function fib(n: number): number { ```rust impl Solution { pub fn fib(n: i32) -> i32 { - if n < 2 { - return n; + let a = vec![vec![1, 1], vec![1, 0]]; + pow(a, n as usize)[0][1] + } +} + +fn mul(a: Vec >, b: Vec >) -> Vec > { + let m = a.len(); + let n = b[0].len(); + let mut c = vec![vec![0; n]; m]; + + for i in 0..m { + for j in 0..n { + for k in 0..b.len() { + c[i][j] += a[i][k] * b[k][j]; + } + } + } + c +} + +fn pow(mut a: Vec >, mut n: usize) -> Vec > { + let mut res = vec![vec![1, 0], vec![0, 1]]; + + while n > 0 { + if n & 1 == 1 { + res = mul(res, a.clone()); + } + a = mul(a.clone(), a); + n >>= 1; + } + res +} +``` + +#### JavaScript + +```js +/** + * @param {number} n + * @return {number} + */ +var fib = function (n) { + const a = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +}; + +function mul(a, b) { + const m = a.length, + n = b[0].length; + const c = Array.from({ length: m }, () => Array(n).fill(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] += a[i][k] * b[k][j]; + } + } + } + return c; +} + +function pow(a, n) { + let res = [ + [1, 0], + [0, 1], + ]; + while (n > 0) { + if (n & 1) { + res = mul(res, a); } - Self::fib(n - 1) + Self::fib(n - 2) + a = mul(a, a); + n >>= 1; } + return res; } ``` diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution.js b/solution/0500-0599/0509.Fibonacci Number/Solution.js index 276f819e85299..1003b78a37cff 100644 --- a/solution/0500-0599/0509.Fibonacci Number/Solution.js +++ b/solution/0500-0599/0509.Fibonacci Number/Solution.js @@ -3,12 +3,9 @@ * @return {number} */ var fib = function (n) { - let a = 0; - let b = 1; + let [a, b] = [0, 1]; while (n--) { - const c = a + b; - a = b; - b = c; + [a, b] = [b, a + b]; } return a; }; diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution.php b/solution/0500-0599/0509.Fibonacci Number/Solution.php index 3f7633947f92b..06c1a7c82d10c 100644 --- a/solution/0500-0599/0509.Fibonacci Number/Solution.php +++ b/solution/0500-0599/0509.Fibonacci Number/Solution.php @@ -1,16 +1,17 @@ class Solution { + /** * @param Integer $n * @return Integer */ function fib($n) { - if ($n == 0 || $n == 1) { - return $n; + $a = 0; + $b = 1; + for ($i = 0; $i < $n; $i++) { + $temp = $a; + $a = $b; + $b = $temp + $b; } - $dp = [0, 1]; - for ($i = 2; $i <= $n; $i++) { - $dp[$i] = $dp[$i - 2] + $dp[$i - 1]; - } - return $dp[$n]; + return $a; } } diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution.ts b/solution/0500-0599/0509.Fibonacci Number/Solution.ts index fb1d523630de5..fd3aefdba2712 100644 --- a/solution/0500-0599/0509.Fibonacci Number/Solution.ts +++ b/solution/0500-0599/0509.Fibonacci Number/Solution.ts @@ -1,7 +1,6 @@ function fib(n: number): number { - let a = 0; - let b = 1; - for (let i = 0; i < n; i++) { + let [a, b] = [0, 1]; + while (n--) { [a, b] = [b, a + b]; } return a; diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.cpp b/solution/0500-0599/0509.Fibonacci Number/Solution2.cpp new file mode 100644 index 0000000000000..21eb8d6c50a0d --- /dev/null +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.cpp @@ -0,0 +1,32 @@ +class Solution { +public: + int fib(int n) { + vector > a = {{1, 1}, {1, 0}}; + return qpow(a, n)[0][1]; + } + + vector > mul(vector >& a, vector >& b) { + int m = a.size(), n = b[0].size(); + vector > c(m, vector (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]; + } + } + } + return c; + } + + vector > qpow(vector >& a, int n) { + vector > res = {{1, 0}}; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +}; diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.go b/solution/0500-0599/0509.Fibonacci Number/Solution2.go new file mode 100644 index 0000000000000..0bc01918b6a17 --- /dev/null +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.go @@ -0,0 +1,32 @@ +func fib(n int) int { + a := [][]int{{1, 1}, {1, 0}} + return pow(a, n)[0][1] +} + +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] + } + } + } + return c +} + +func pow(a [][]int, n int) [][]int { + res := [][]int{{1, 0}} + for n > 0 { + if n&1 == 1 { + res = mul(res, a) + } + a = mul(a, a) + n >>= 1 + } + return res +} diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.java b/solution/0500-0599/0509.Fibonacci Number/Solution2.java new file mode 100644 index 0000000000000..3949ec43be9cf --- /dev/null +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.java @@ -0,0 +1,31 @@ +class Solution { + public int fib(int n) { + int[][] a = {{1, 1}, {1, 0}}; + return pow(a, n)[0][1]; + } + + private int[][] mul(int[][] a, int[][] b) { + int m = a.length, n = b[0].length; + int[][] c = new int[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]; + } + } + } + return c; + } + + private int[][] pow(int[][] a, int n) { + int[][] res = {{1, 0}}; + while (n > 0) { + if ((n & 1) == 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; + } +} diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.js b/solution/0500-0599/0509.Fibonacci Number/Solution2.js new file mode 100644 index 0000000000000..cfbe90d76b63f --- /dev/null +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.js @@ -0,0 +1,40 @@ +/** + * @param {number} n + * @return {number} + */ +var fib = function (n) { + const a = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +}; + +function mul(a, b) { + const m = a.length, + n = b[0].length; + const c = Array.from({ length: m }, () => Array(n).fill(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] += a[i][k] * b[k][j]; + } + } + } + return c; +} + +function pow(a, n) { + let res = [ + [1, 0], + [0, 1], + ]; + while (n > 0) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; + } + return res; +} diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.py b/solution/0500-0599/0509.Fibonacci Number/Solution2.py new file mode 100644 index 0000000000000..76cadf3002dcf --- /dev/null +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.py @@ -0,0 +1,13 @@ +import numpy as np + + +class Solution: + def fib(self, n: int) -> int: + factor = np.asmatrix([(1, 1), (1, 0)], np.dtype("O")) + res = np.asmatrix([(1, 0)], np.dtype("O")) + while n: + if n & 1: + res = res * factor + factor = factor * factor + n >>= 1 + return res[0, 1] diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.rs b/solution/0500-0599/0509.Fibonacci Number/Solution2.rs index 64505cf3d584b..e54b5add3da7e 100644 --- a/solution/0500-0599/0509.Fibonacci Number/Solution2.rs +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.rs @@ -1,8 +1,34 @@ -impl Solution { - pub fn fib(n: i32) -> i32 { - if n < 2 { - return n; - } - Self::fib(n - 1) + Self::fib(n - 2) - } -} +impl Solution { + pub fn fib(n: i32) -> i32 { + let a = vec![vec![1, 1], vec![1, 0]]; + pow(a, n as usize)[0][1] + } +} + +fn mul(a: Vec >, b: Vec >) -> Vec > { + let m = a.len(); + let n = b[0].len(); + let mut c = vec![vec![0; n]; m]; + + for i in 0..m { + for j in 0..n { + for k in 0..b.len() { + c[i][j] += a[i][k] * b[k][j]; + } + } + } + c +} + +fn pow(mut a: Vec >, mut n: usize) -> Vec > { + let mut res = vec![vec![1, 0], vec![0, 1]]; + + while n > 0 { + if n & 1 == 1 { + res = mul(res, a.clone()); + } + a = mul(a.clone(), a); + n >>= 1; + } + res +} diff --git a/solution/0500-0599/0509.Fibonacci Number/Solution2.ts b/solution/0500-0599/0509.Fibonacci Number/Solution2.ts index bd8a883d4f0ba..621c341f4982a 100644 --- a/solution/0500-0599/0509.Fibonacci Number/Solution2.ts +++ b/solution/0500-0599/0509.Fibonacci Number/Solution2.ts @@ -1,6 +1,32 @@ function fib(n: number): number { - if (n < 2) { - return n; + const a: number[][] = [ + [1, 1], + [1, 0], + ]; + return pow(a, n)[0][1]; +} + +function mul(a: number[][], b: number[][]): number[][] { + 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] += a[i][k] * b[k][j]; + } + } + } + return c; +} + +function pow(a: number[][], n: number): number[][] { + let res = [[1, 0]]; + while (n) { + if (n & 1) { + res = mul(res, a); + } + a = mul(a, a); + n >>= 1; } - return fib(n - 1) + fib(n - 2); + return res; } diff --git a/solution/1100-1199/1137.N-th Tribonacci Number/README.md b/solution/1100-1199/1137.N-th Tribonacci Number/README.md index d5239f0d61c35..deaef11a7eb04 100644 --- a/solution/1100-1199/1137.N-th Tribonacci Number/README.md +++ b/solution/1100-1199/1137.N-th Tribonacci Number/README.md @@ -253,32 +253,24 @@ $$ #### Python3 ```python +import numpy as np + + class Solution: def tribonacci(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1, 0]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - if n == 0: return 0 if n < 3: return 1 - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 3)[0]) + factor = np.asmatrix([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) + res = np.asmatrix([(1, 1, 0)], np.dtype("O")) + n -= 3 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res.sum() ``` #### Java @@ -473,37 +465,4 @@ function pow(a, n) { - - -### 方法三 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def tribonacci(self, n: int) -> int: - if n == 0: - return 0 - if n < 3: - return 1 - factor = np.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(1, 1, 0)], np.dtype("O")) - n -= 3 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res.sum() -``` - - - - - diff --git a/solution/1100-1199/1137.N-th Tribonacci Number/README_EN.md b/solution/1100-1199/1137.N-th Tribonacci Number/README_EN.md index 794b421babefb..110e5fd597d5e 100644 --- a/solution/1100-1199/1137.N-th Tribonacci Number/README_EN.md +++ b/solution/1100-1199/1137.N-th Tribonacci Number/README_EN.md @@ -253,32 +253,24 @@ The time complexity is $O(\log n)$, and the space complexity is $O(1)$. #### Python3 ```python +import numpy as np + + class Solution: def tribonacci(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c - - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1, 0]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res - if n == 0: return 0 if n < 3: return 1 - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 3)[0]) + factor = np.asmatrix([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) + res = np.asmatrix([(1, 1, 0)], np.dtype("O")) + n -= 3 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res.sum() ``` #### Java @@ -473,37 +465,4 @@ function pow(a, n) { - - -### Solution 3 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def tribonacci(self, n: int) -> int: - if n == 0: - return 0 - if n < 3: - return 1 - factor = np.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(1, 1, 0)], np.dtype("O")) - n -= 3 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res.sum() -``` - - - - - diff --git a/solution/1100-1199/1137.N-th Tribonacci Number/Solution2.py b/solution/1100-1199/1137.N-th Tribonacci Number/Solution2.py index 87ffef8a51d06..9b0594c334100 100644 --- a/solution/1100-1199/1137.N-th Tribonacci Number/Solution2.py +++ b/solution/1100-1199/1137.N-th Tribonacci Number/Solution2.py @@ -1,26 +1,18 @@ -class Solution: - def tribonacci(self, n: int) -> int: - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(a[0])): - c[i][j] = c[i][j] + a[i][k] * b[k][j] - return c +import numpy as np - def pow(a: List[List[int]], n: int) -> List[List[int]]: - res = [[1, 1, 0]] - while n: - if n & 1: - res = mul(res, a) - n >>= 1 - a = mul(a, a) - return res +class Solution: + def tribonacci(self, n: int) -> int: if n == 0: return 0 if n < 3: return 1 - a = [[1, 1, 0], [1, 0, 1], [1, 0, 0]] - return sum(pow(a, n - 3)[0]) + factor = np.asmatrix([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) + res = np.asmatrix([(1, 1, 0)], np.dtype("O")) + n -= 3 + while n: + if n & 1: + res *= factor + factor *= factor + n >>= 1 + return res.sum() diff --git a/solution/1100-1199/1137.N-th Tribonacci Number/Solution3.py b/solution/1100-1199/1137.N-th Tribonacci Number/Solution3.py deleted file mode 100644 index df667a1579603..0000000000000 --- a/solution/1100-1199/1137.N-th Tribonacci Number/Solution3.py +++ /dev/null @@ -1,18 +0,0 @@ -import numpy as np - - -class Solution: - def tribonacci(self, n: int) -> int: - if n == 0: - return 0 - if n < 3: - return 1 - factor = np.mat([(1, 1, 0), (1, 0, 1), (1, 0, 0)], np.dtype("O")) - res = np.mat([(1, 1, 0)], np.dtype("O")) - n -= 3 - while n: - if n & 1: - res *= factor - factor *= factor - n >>= 1 - return res.sum() diff --git a/solution/1200-1299/1220.Count Vowels Permutation/README.md b/solution/1200-1299/1220.Count Vowels Permutation/README.md index 38aa29254f77e..be5e299ff6df6 100644 --- a/solution/1200-1299/1220.Count Vowels Permutation/README.md +++ b/solution/1200-1299/1220.Count Vowels Permutation/README.md @@ -258,37 +258,30 @@ var countVowelPermutation = function (n) { #### Python3 ```python +import numpy as np + + class Solution: def countVowelPermutation(self, n: int) -> int: mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(b)): - c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % mod - return c - - def pow(a: List[List[int]], n: int) -> List[int]: - res = [[1] * len(a)] - while n: - if n & 1: - res = mul(res, a) - a = mul(a, a) - n >>= 1 - return res - - a = [ - [0, 1, 0, 0, 0], - [1, 0, 1, 0, 0], - [1, 1, 0, 1, 1], - [0, 0, 1, 0, 1], - [1, 0, 0, 0, 0], - ] - res = pow(a, n - 1) - return sum(map(sum, res)) % mod + factor = np.asmatrix( + [ + (0, 1, 0, 0, 0), + (1, 0, 1, 0, 0), + (1, 1, 0, 1, 1), + (0, 0, 1, 0, 1), + (1, 0, 0, 0, 0), + ], + np.dtype("O"), + ) + res = np.asmatrix([(1, 1, 1, 1, 1)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res = res * factor % mod + factor = factor * factor % mod + n >>= 1 + return res.sum() % mod ``` #### Java @@ -529,71 +522,4 @@ function pow(a, n) { - - -### 方法三 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def countVowelPermutation(self, n: int) -> int: - mod = 10**9 + 7 - factor = np.mat( - [ - (0, 1, 0, 0, 0), - (1, 0, 1, 0, 0), - (1, 1, 0, 1, 1), - (0, 0, 1, 0, 1), - (1, 0, 0, 0, 0), - ], - np.dtype("O"), - ) - res = np.mat([(1, 1, 1, 1, 1)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res = res * factor % mod - factor = factor * factor % mod - n >>= 1 - return res.sum() % mod -``` - -#### Java - -```java -class Solution { - public int countVowelPermutation(int n) { - final int mod = 1000000007; - long countA = 1, countE = 1, countI = 1, countO = 1, countU = 1; - for (int length = 1; length < n; length++) { - // Calculate the next counts for each vowel based on the previous counts - long nextCountA = countE; - long nextCountE = (countA + countI) % mod; - long nextCountI = (countA + countE + countO + countU) % mod; - long nextCountO = (countI + countU) % mod; - long nextCountU = countA; - // Update the counts with the newly calculated values for the next length - countA = nextCountA; - countE = nextCountE; - countI = nextCountI; - countO = nextCountO; - countU = nextCountU; - } - // Calculate the total count of valid strings for length n - long totalCount = (countA + countE + countI + countO + countU) % mod; - return (int) totalCount; - } -} -``` - - - - - diff --git a/solution/1200-1299/1220.Count Vowels Permutation/README_EN.md b/solution/1200-1299/1220.Count Vowels Permutation/README_EN.md index afdc3e5e9d2f8..99b8d73595ed8 100644 --- a/solution/1200-1299/1220.Count Vowels Permutation/README_EN.md +++ b/solution/1200-1299/1220.Count Vowels Permutation/README_EN.md @@ -259,37 +259,30 @@ The time complexity is $O(C^3 \times \log n)$, and the space complexity is $O(C^ #### Python3 ```python +import numpy as np + + class Solution: def countVowelPermutation(self, n: int) -> int: mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(b)): - c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % mod - return c - - def pow(a: List[List[int]], n: int) -> List[int]: - res = [[1] * len(a)] - while n: - if n & 1: - res = mul(res, a) - a = mul(a, a) - n >>= 1 - return res - - a = [ - [0, 1, 0, 0, 0], - [1, 0, 1, 0, 0], - [1, 1, 0, 1, 1], - [0, 0, 1, 0, 1], - [1, 0, 0, 0, 0], - ] - res = pow(a, n - 1) - return sum(map(sum, res)) % mod + factor = np.asmatrix( + [ + (0, 1, 0, 0, 0), + (1, 0, 1, 0, 0), + (1, 1, 0, 1, 1), + (0, 0, 1, 0, 1), + (1, 0, 0, 0, 0), + ], + np.dtype("O"), + ) + res = np.asmatrix([(1, 1, 1, 1, 1)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res = res * factor % mod + factor = factor * factor % mod + n >>= 1 + return res.sum() % mod ``` #### Java @@ -530,71 +523,4 @@ function pow(a, n) { - - -### Solution 3 - - - -#### Python3 - -```python -import numpy as np - - -class Solution: - def countVowelPermutation(self, n: int) -> int: - mod = 10**9 + 7 - factor = np.mat( - [ - (0, 1, 0, 0, 0), - (1, 0, 1, 0, 0), - (1, 1, 0, 1, 1), - (0, 0, 1, 0, 1), - (1, 0, 0, 0, 0), - ], - np.dtype("O"), - ) - res = np.mat([(1, 1, 1, 1, 1)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res = res * factor % mod - factor = factor * factor % mod - n >>= 1 - return res.sum() % mod -``` - -#### Java - -```java -class Solution { - public int countVowelPermutation(int n) { - final int mod = 1000000007; - long countA = 1, countE = 1, countI = 1, countO = 1, countU = 1; - for (int length = 1; length < n; length++) { - // Calculate the next counts for each vowel based on the previous counts - long nextCountA = countE; - long nextCountE = (countA + countI) % mod; - long nextCountI = (countA + countE + countO + countU) % mod; - long nextCountO = (countI + countU) % mod; - long nextCountU = countA; - // Update the counts with the newly calculated values for the next length - countA = nextCountA; - countE = nextCountE; - countI = nextCountI; - countO = nextCountO; - countU = nextCountU; - } - // Calculate the total count of valid strings for length n - long totalCount = (countA + countE + countI + countO + countU) % mod; - return (int) totalCount; - } -} -``` - - - - - diff --git a/solution/1200-1299/1220.Count Vowels Permutation/Solution2.py b/solution/1200-1299/1220.Count Vowels Permutation/Solution2.py index 33ebef87259db..ecd8d8c2c6dfa 100644 --- a/solution/1200-1299/1220.Count Vowels Permutation/Solution2.py +++ b/solution/1200-1299/1220.Count Vowels Permutation/Solution2.py @@ -1,31 +1,24 @@ +import numpy as np + + class Solution: def countVowelPermutation(self, n: int) -> int: mod = 10**9 + 7 - - def mul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]: - m, n = len(a), len(b[0]) - c = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - for k in range(len(b)): - c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % mod - return c - - def pow(a: List[List[int]], n: int) -> List[int]: - res = [[1] * len(a)] - while n: - if n & 1: - res = mul(res, a) - a = mul(a, a) - n >>= 1 - return res - - a = [ - [0, 1, 0, 0, 0], - [1, 0, 1, 0, 0], - [1, 1, 0, 1, 1], - [0, 0, 1, 0, 1], - [1, 0, 0, 0, 0], - ] - res = pow(a, n - 1) - return sum(map(sum, res)) % mod + factor = np.asmatrix( + [ + (0, 1, 0, 0, 0), + (1, 0, 1, 0, 0), + (1, 1, 0, 1, 1), + (0, 0, 1, 0, 1), + (1, 0, 0, 0, 0), + ], + np.dtype("O"), + ) + res = np.asmatrix([(1, 1, 1, 1, 1)], np.dtype("O")) + n -= 1 + while n: + if n & 1: + res = res * factor % mod + factor = factor * factor % mod + n >>= 1 + return res.sum() % mod diff --git a/solution/1200-1299/1220.Count Vowels Permutation/Solution3.java b/solution/1200-1299/1220.Count Vowels Permutation/Solution3.java deleted file mode 100644 index 0d0736cf81b26..0000000000000 --- a/solution/1200-1299/1220.Count Vowels Permutation/Solution3.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public int countVowelPermutation(int n) { - final int mod = 1000000007; - long countA = 1, countE = 1, countI = 1, countO = 1, countU = 1; - for (int length = 1; length < n; length++) { - // Calculate the next counts for each vowel based on the previous counts - long nextCountA = countE; - long nextCountE = (countA + countI) % mod; - long nextCountI = (countA + countE + countO + countU) % mod; - long nextCountO = (countI + countU) % mod; - long nextCountU = countA; - // Update the counts with the newly calculated values for the next length - countA = nextCountA; - countE = nextCountE; - countI = nextCountI; - countO = nextCountO; - countU = nextCountU; - } - // Calculate the total count of valid strings for length n - long totalCount = (countA + countE + countI + countO + countU) % mod; - return (int) totalCount; - } -} \ No newline at end of file diff --git a/solution/1200-1299/1220.Count Vowels Permutation/Solution3.py b/solution/1200-1299/1220.Count Vowels Permutation/Solution3.py deleted file mode 100644 index 47eaa67aeaf8d..0000000000000 --- a/solution/1200-1299/1220.Count Vowels Permutation/Solution3.py +++ /dev/null @@ -1,24 +0,0 @@ -import numpy as np - - -class Solution: - def countVowelPermutation(self, n: int) -> int: - mod = 10**9 + 7 - factor = np.mat( - [ - (0, 1, 0, 0, 0), - (1, 0, 1, 0, 0), - (1, 1, 0, 1, 1), - (0, 0, 1, 0, 1), - (1, 0, 0, 0, 0), - ], - np.dtype("O"), - ) - res = np.mat([(1, 1, 1, 1, 1)], np.dtype("O")) - n -= 1 - while n: - if n & 1: - res = res * factor % mod - factor = factor * factor % mod - n >>= 1 - return res.sum() % mod