diff --git a/solution/0500-0599/0557.Reverse Words in a String III/README.md b/solution/0500-0599/0557.Reverse Words in a String III/README.md index 3a813faa30db1..a8b7c3f192717 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/README.md +++ b/solution/0500-0599/0557.Reverse Words in a String III/README.md @@ -53,7 +53,11 @@ tags: -### 方法一 +### 方法一:模拟 + +我们可以将字符串 $\textit{s}$ 按照空格分割成单词数组 $\textit{words}$,然后将每个单词反转后再拼接成字符串。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{s}$ 的长度。 @@ -62,7 +66,7 @@ tags: ```python class Solution: def reverseWords(self, s: str) -> str: - return ' '.join([t[::-1] for t in s.split(' ')]) + return " ".join(t[::-1] for t in s.split()) ``` #### Java @@ -70,14 +74,11 @@ class Solution: ```java class Solution { public String reverseWords(String s) { - StringBuilder res = new StringBuilder(); - for (String t : s.split(" ")) { - for (int i = t.length() - 1; i >= 0; --i) { - res.append(t.charAt(i)); - } - res.append(" "); + String[] words = s.split(" "); + for (int i = 0; i < words.length; ++i) { + words[i] = new StringBuilder(words[i]).reverse().toString(); } - return res.substring(0, res.length() - 1); + return String.join(" ", words); } } ``` @@ -88,14 +89,16 @@ class Solution { class Solution { public: string reverseWords(string s) { - for (int i = 0, n = s.size(); i < n; ++i) { - int j = i; - while (++j < n && s[j] != ' ') - ; - reverse(s.begin() + i, s.begin() + j); - i = j; + stringstream ss(s); + string t; + string ans; + while (ss >> t) { + reverse(t.begin(), t.end()); + ans += t; + ans.push_back(' '); } - return s; + ans.pop_back(); + return ans; } }; ``` @@ -104,18 +107,13 @@ public: ```go func reverseWords(s string) string { - t := []byte(s) - for i := 0; i < len(t); i++ { - j := i - for j < len(t) && t[j] != ' ' { - j++ - } - for st, ed := i, j-1; st < ed; st, ed = st+1, ed-1 { - t[st], t[ed] = t[ed], t[st] - } - i = j + words := strings.Fields(s) + for i, w := range words { + t := []byte(w) + slices.Reverse(t) + words[i] = string(t) } - return string(t) + return strings.Join(words, " ") } ``` @@ -124,14 +122,8 @@ func reverseWords(s string) string { ```ts function reverseWords(s: string): string { return s - .split(/\s+/) - .map(str => { - let res = ''; - for (const c of str) { - res = c + res; - } - return res; - }) + .split(' ') + .map(t => t.split('').reverse().join('')) .join(' '); } ``` @@ -149,6 +141,21 @@ impl Solution { } ``` +#### JavaScript + +```js +/** + * @param {string} s + * @return {string} + */ +var reverseWords = function (s) { + return s + .split(' ') + .map(t => t.split('').reverse().join('')) + .join(' '); +}; +``` + #### PHP ```php @@ -158,11 +165,11 @@ class Solution { * @return String */ function reverseWords($s) { - $sArr = explode(' ', $s); - for ($i = 0; $i < count($sArr); $i++) { - $sArr[$i] = strrev($sArr[$i]); + $words = explode(' ', $s); + foreach ($words as $i => $word) { + $words[$i] = strrev($word); } - return implode(' ', $sArr); + return implode(' ', $words); } } ``` diff --git a/solution/0500-0599/0557.Reverse Words in a String III/README_EN.md b/solution/0500-0599/0557.Reverse Words in a String III/README_EN.md index a98096a9cc6d0..4dc3bda344049 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/README_EN.md +++ b/solution/0500-0599/0557.Reverse Words in a String III/README_EN.md @@ -51,7 +51,11 @@ tags: -### Solution 1 +### Solution 1: Simulation + +We can split the string $\textit{s}$ into an array of words $\textit{words}$ by spaces, then reverse each word and concatenate them back into a string. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $\textit{s}$. @@ -60,7 +64,7 @@ tags: ```python class Solution: def reverseWords(self, s: str) -> str: - return ' '.join([t[::-1] for t in s.split(' ')]) + return " ".join(t[::-1] for t in s.split()) ``` #### Java @@ -68,14 +72,11 @@ class Solution: ```java class Solution { public String reverseWords(String s) { - StringBuilder res = new StringBuilder(); - for (String t : s.split(" ")) { - for (int i = t.length() - 1; i >= 0; --i) { - res.append(t.charAt(i)); - } - res.append(" "); + String[] words = s.split(" "); + for (int i = 0; i < words.length; ++i) { + words[i] = new StringBuilder(words[i]).reverse().toString(); } - return res.substring(0, res.length() - 1); + return String.join(" ", words); } } ``` @@ -86,14 +87,16 @@ class Solution { class Solution { public: string reverseWords(string s) { - for (int i = 0, n = s.size(); i < n; ++i) { - int j = i; - while (++j < n && s[j] != ' ') - ; - reverse(s.begin() + i, s.begin() + j); - i = j; + stringstream ss(s); + string t; + string ans; + while (ss >> t) { + reverse(t.begin(), t.end()); + ans += t; + ans.push_back(' '); } - return s; + ans.pop_back(); + return ans; } }; ``` @@ -102,18 +105,13 @@ public: ```go func reverseWords(s string) string { - t := []byte(s) - for i := 0; i < len(t); i++ { - j := i - for j < len(t) && t[j] != ' ' { - j++ - } - for st, ed := i, j-1; st < ed; st, ed = st+1, ed-1 { - t[st], t[ed] = t[ed], t[st] - } - i = j + words := strings.Fields(s) + for i, w := range words { + t := []byte(w) + slices.Reverse(t) + words[i] = string(t) } - return string(t) + return strings.Join(words, " ") } ``` @@ -122,14 +120,8 @@ func reverseWords(s string) string { ```ts function reverseWords(s: string): string { return s - .split(/\s+/) - .map(str => { - let res = ''; - for (const c of str) { - res = c + res; - } - return res; - }) + .split(' ') + .map(t => t.split('').reverse().join('')) .join(' '); } ``` @@ -147,6 +139,21 @@ impl Solution { } ``` +#### JavaScript + +```js +/** + * @param {string} s + * @return {string} + */ +var reverseWords = function (s) { + return s + .split(' ') + .map(t => t.split('').reverse().join('')) + .join(' '); +}; +``` + #### PHP ```php @@ -156,11 +163,11 @@ class Solution { * @return String */ function reverseWords($s) { - $sArr = explode(' ', $s); - for ($i = 0; $i < count($sArr); $i++) { - $sArr[$i] = strrev($sArr[$i]); + $words = explode(' ', $s); + foreach ($words as $i => $word) { + $words[$i] = strrev($word); } - return implode(' ', $sArr); + return implode(' ', $words); } } ``` diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.cpp b/solution/0500-0599/0557.Reverse Words in a String III/Solution.cpp index 33b5ffd55f74b..287c205b7de80 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.cpp +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.cpp @@ -1,13 +1,15 @@ class Solution { public: string reverseWords(string s) { - for (int i = 0, n = s.size(); i < n; ++i) { - int j = i; - while (++j < n && s[j] != ' ') - ; - reverse(s.begin() + i, s.begin() + j); - i = j; + stringstream ss(s); + string t; + string ans; + while (ss >> t) { + reverse(t.begin(), t.end()); + ans += t; + ans.push_back(' '); } - return s; + ans.pop_back(); + return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.go b/solution/0500-0599/0557.Reverse Words in a String III/Solution.go index 0a23fac8dd1f6..79d1ec1383c22 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.go +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.go @@ -1,14 +1,9 @@ func reverseWords(s string) string { - t := []byte(s) - for i := 0; i < len(t); i++ { - j := i - for j < len(t) && t[j] != ' ' { - j++ - } - for st, ed := i, j-1; st < ed; st, ed = st+1, ed-1 { - t[st], t[ed] = t[ed], t[st] - } - i = j + words := strings.Fields(s) + for i, w := range words { + t := []byte(w) + slices.Reverse(t) + words[i] = string(t) } - return string(t) -} \ No newline at end of file + return strings.Join(words, " ") +} diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.java b/solution/0500-0599/0557.Reverse Words in a String III/Solution.java index 5f3199f7e0d3e..cf899efa0c8dc 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.java +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.java @@ -1,12 +1,9 @@ class Solution { public String reverseWords(String s) { - StringBuilder res = new StringBuilder(); - for (String t : s.split(" ")) { - for (int i = t.length() - 1; i >= 0; --i) { - res.append(t.charAt(i)); - } - res.append(" "); + String[] words = s.split(" "); + for (int i = 0; i < words.length; ++i) { + words[i] = new StringBuilder(words[i]).reverse().toString(); } - return res.substring(0, res.length() - 1); + return String.join(" ", words); } -} \ No newline at end of file +} diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.js b/solution/0500-0599/0557.Reverse Words in a String III/Solution.js new file mode 100644 index 0000000000000..22035b0cabacb --- /dev/null +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.js @@ -0,0 +1,10 @@ +/** + * @param {string} s + * @return {string} + */ +var reverseWords = function (s) { + return s + .split(' ') + .map(t => t.split('').reverse().join('')) + .join(' '); +}; diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.php b/solution/0500-0599/0557.Reverse Words in a String III/Solution.php index 4e17b554f7695..b95f11d75ecba 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.php +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.php @@ -4,10 +4,10 @@ class Solution { * @return String */ function reverseWords($s) { - $sArr = explode(' ', $s); - for ($i = 0; $i < count($sArr); $i++) { - $sArr[$i] = strrev($sArr[$i]); + $words = explode(' ', $s); + foreach ($words as $i => $word) { + $words[$i] = strrev($word); } - return implode(' ', $sArr); + return implode(' ', $words); } } diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.py b/solution/0500-0599/0557.Reverse Words in a String III/Solution.py index d818a49cb4d9a..604b7b39c4def 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.py +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.py @@ -1,3 +1,3 @@ class Solution: def reverseWords(self, s: str) -> str: - return ' '.join([t[::-1] for t in s.split(' ')]) + return " ".join(t[::-1] for t in s.split()) diff --git a/solution/0500-0599/0557.Reverse Words in a String III/Solution.ts b/solution/0500-0599/0557.Reverse Words in a String III/Solution.ts index ea2d683bb8287..38ee564a6f506 100644 --- a/solution/0500-0599/0557.Reverse Words in a String III/Solution.ts +++ b/solution/0500-0599/0557.Reverse Words in a String III/Solution.ts @@ -1,12 +1,6 @@ function reverseWords(s: string): string { return s - .split(/\s+/) - .map(str => { - let res = ''; - for (const c of str) { - res = c + res; - } - return res; - }) + .split(' ') + .map(t => t.split('').reverse().join('')) .join(' '); } diff --git a/solution/0500-0599/0576.Out of Boundary Paths/README.md b/solution/0500-0599/0576.Out of Boundary Paths/README.md index d601637a01028..d50f6c6bfd6ce 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/README.md +++ b/solution/0500-0599/0576.Out of Boundary Paths/README.md @@ -55,9 +55,15 @@ tags: ### 方法一:记忆化搜索 -定义 `dfs(i, j, k)` 表示当前位于坐标 $(i, j)$,且剩余移动次数为 $k$ 时,可以出界的路径数。记忆化搜索即可。 +我们定义一个函数 $\textit{dfs}(i, j, k)$ 表示从坐标 $(i, j)$ 出发,还剩下 $k$ 步可以移动的情况下,可以移出边界的路径数量。 -时间复杂度 $O(m\times n\times k)$,空间复杂度 $O(m\times n\times k)$。其中 $m$, $n$, $k$ 分别表示网格的行数、列数、最大可移动次数。 +在函数 $\textit{dfs}(i, j, k)$ 中,我们首先处理边界情况,如果当前坐标 $(i, j)$ 不在网格范围内,如果 $k \geq 0$,则返回 $1$,否则返回 $0$。如果 $k \leq 0$,说明还在网格内,但是已经没有移动次数了,返回 $0$。接下来,我们遍历四个方向,移动到下一个坐标 $(x, y)$,然后递归调用 $\textit{dfs}(x, y, k - 1)$,并将结果累加到答案中。 + +在主函数中,我们调用 $\textit{dfs}(startRow, startColumn, maxMove)$,即从起始坐标 $(\textit{startRow}, \textit{startColumn})$ 出发,还剩下 $\textit{maxMove}$ 步可以移动的情况下,可以移出边界的路径数量。 + +为了避免重复计算,我们可以使用记忆化搜索。 + +时间复杂度 $O(m \times n \times k)$,空间复杂度 $O(m \times n \times k)$。其中 $m$ 和 $n$ 分别是网格的行数和列数,而 $k$ 是可以移动的步数,本题中 $k = \textit{maxMove} \leq 50$。 @@ -69,19 +75,19 @@ class Solution: self, m: int, n: int, maxMove: int, startRow: int, startColumn: int ) -> int: @cache - def dfs(i, j, k): - if i < 0 or j < 0 or i >= m or j >= n: - return 1 + def dfs(i: int, j: int, k: int) -> int: + if not 0 <= i < m or not 0 <= j < n: + return int(k >= 0) if k <= 0: return 0 - res = 0 - for a, b in [[-1, 0], [1, 0], [0, 1], [0, -1]]: + ans = 0 + for a, b in pairwise(dirs): x, y = i + a, j + b - res += dfs(x, y, k - 1) - res %= mod - return res + ans = (ans + dfs(x, y, k - 1)) % mod + return ans mod = 10**9 + 7 + dirs = (-1, 0, 1, 0, -1) return dfs(startRow, startColumn, maxMove) ``` @@ -89,43 +95,34 @@ class Solution: ```java class Solution { - private int m; - private int n; - private int[][][] f; - private static final int[] DIRS = {-1, 0, 1, 0, -1}; - private static final int MOD = (int) 1e9 + 7; + private int m, n; + private Integer[][][] f; + private final int mod = (int) 1e9 + 7; public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { this.m = m; this.n = n; - f = new int[m + 1][n + 1][maxMove + 1]; - for (var a : f) { - for (var b : a) { - Arrays.fill(b, -1); - } - } + f = new Integer[m][n][maxMove + 1]; return dfs(startRow, startColumn, maxMove); } private int dfs(int i, int j, int k) { if (i < 0 || i >= m || j < 0 || j >= n) { - return 1; + return k >= 0 ? 1 : 0; } - if (f[i][j][k] != -1) { - return f[i][j][k]; - } - if (k == 0) { + if (k <= 0) { return 0; } - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + DIRS[t]; - int y = j + DIRS[t + 1]; - res += dfs(x, y, k - 1); - res %= MOD; + if (f[i][j][k] != null) { + return f[i][j][k]; + } + int ans = 0; + final int[] dirs = {-1, 0, 1, 0, -1}; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; } - f[i][j][k] = res; - return res; + return f[i][j][k] = ans; } } ``` @@ -135,32 +132,30 @@ class Solution { ```cpp class Solution { public: - int m; - int n; - const int mod = 1e9 + 7; - int f[51][51][51]; - int dirs[5] = {-1, 0, 1, 0, -1}; - int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { - memset(f, 0xff, sizeof(f)); - this->m = m; - this->n = n; + int f[m][n][maxMove + 1]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + const int dirs[5] = {-1, 0, 1, 0, -1}; + auto dfs = [&](this auto&& dfs, int i, int j, int k) -> int { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0; + } + if (k <= 0) { + return 0; + } + if (f[i][j][k] != -1) { + return f[i][j][k]; + } + int ans = 0; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return f[i][j][k] = ans; + }; return dfs(startRow, startColumn, maxMove); } - - int dfs(int i, int j, int k) { - if (i < 0 || i >= m || j < 0 || j >= n) return 1; - if (f[i][j][k] != -1) return f[i][j][k]; - if (k == 0) return 0; - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + dirs[t], y = j + dirs[t + 1]; - res += dfs(x, y, k - 1); - res %= mod; - } - f[i][j][k] = res; - return res; - } }; ``` @@ -168,9 +163,9 @@ public: ```go func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { - f := make([][][]int, m+1) + f := make([][][]int, m) for i := range f { - f[i] = make([][]int, n+1) + f[i] = make([][]int, n) for j := range f[i] { f[i][j] = make([]int, maxMove+1) for k := range f[i][j] { @@ -178,72 +173,67 @@ func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { } } } - var mod int = 1e9 + 7 - dirs := []int{-1, 0, 1, 0, -1} - var dfs func(i, j, k int) int + const mod int = 1e9 + 7 + var dfs func(int, int, int) int + dirs := [5]int{-1, 0, 1, 0, -1} dfs = func(i, j, k int) int { if i < 0 || i >= m || j < 0 || j >= n { - return 1 + if k >= 0 { + return 1 + } + return 0 + } + if k <= 0 { + return 0 } if f[i][j][k] != -1 { return f[i][j][k] } - if k == 0 { - return 0 - } - res := 0 - for t := 0; t < 4; t++ { - x, y := i+dirs[t], j+dirs[t+1] - res += dfs(x, y, k-1) - res %= mod + ans := 0 + for d := 0; d < 4; d++ { + x, y := i+dirs[d], j+dirs[d+1] + ans = (ans + dfs(x, y, k-1)) % mod } - f[i][j][k] = res - return res + f[i][j][k] = ans + return ans } return dfs(startRow, startColumn, maxMove) } ``` - - - - - - -### 方法二 - - - -#### Java - -```java -class Solution { - public int findPaths(int m, int n, int N, int i, int j) { - final int MOD = (int) (1e9 + 7); - final int[] dirs = new int[] {-1, 0, 1, 0, -1}; - int[][] f = new int[m][n]; - f[i][j] = 1; - int res = 0; - for (int step = 0; step < N; ++step) { - int[][] temp = new int[m][n]; - for (int x = 0; x < m; ++x) { - for (int y = 0; y < n; ++y) { - for (int k = 0; k < 4; ++k) { - int tx = x + dirs[k], ty = y + dirs[k + 1]; - if (tx >= 0 && tx < m && ty >= 0 && ty < n) { - temp[tx][ty] += f[x][y]; - temp[tx][ty] %= MOD; - } else { - res += f[x][y]; - res %= MOD; - } - } - } - } - f = temp; +#### TypeScript + +```ts +function findPaths( + m: number, + n: number, + maxMove: number, + startRow: number, + startColumn: number, +): number { + const f = Array.from({ length: m }, () => + Array.from({ length: n }, () => Array(maxMove + 1).fill(-1)), + ); + const mod = 1000000007; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number, k: number): number => { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0 ? 1 : 0; } - return res; - } + if (k <= 0) { + return 0; + } + if (f[i][j][k] !== -1) { + return f[i][j][k]; + } + let ans = 0; + for (let d = 0; d < 4; ++d) { + const [x, y] = [i + dirs[d], j + dirs[d + 1]]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return (f[i][j][k] = ans); + }; + return dfs(startRow, startColumn, maxMove); } ``` diff --git a/solution/0500-0599/0576.Out of Boundary Paths/README_EN.md b/solution/0500-0599/0576.Out of Boundary Paths/README_EN.md index 0bfcd2f4f2243..0aa769aec46e9 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/README_EN.md +++ b/solution/0500-0599/0576.Out of Boundary Paths/README_EN.md @@ -51,7 +51,17 @@ tags: -### Solution 1 +### Solution 1: Memoization Search + +We define a function $\textit{dfs}(i, j, k)$ to represent the number of paths that can move out of the boundary starting from coordinates $(i, j)$ with $k$ steps remaining. + +In the function $\textit{dfs}(i, j, k)$, we first handle the boundary cases. If the current coordinates $(i, j)$ are out of the grid range, return $1$ if $k \geq 0$, otherwise return $0$. If $k \leq 0$, it means we are still within the grid but have no remaining moves, so return $0$. Next, we iterate over the four directions, move to the next coordinates $(x, y)$, then recursively call $\textit{dfs}(x, y, k - 1)$, and accumulate the results to the answer. + +In the main function, we call $\textit{dfs}(startRow, startColumn, maxMove)$, which represents the number of paths that can move out of the boundary starting from the initial coordinates $(\textit{startRow}, \textit{startColumn})$ with $\textit{maxMove}$ steps remaining. + +To avoid redundant calculations, we can use memoization. + +The time complexity is $O(m \times n \times k)$, and the space complexity is $O(m \times n \times k)$. Here, $m$ and $n$ are the number of rows and columns of the grid, and $k$ is the number of steps that can be moved, with $k = \textit{maxMove} \leq 50$. @@ -63,19 +73,19 @@ class Solution: self, m: int, n: int, maxMove: int, startRow: int, startColumn: int ) -> int: @cache - def dfs(i, j, k): - if i < 0 or j < 0 or i >= m or j >= n: - return 1 + def dfs(i: int, j: int, k: int) -> int: + if not 0 <= i < m or not 0 <= j < n: + return int(k >= 0) if k <= 0: return 0 - res = 0 - for a, b in [[-1, 0], [1, 0], [0, 1], [0, -1]]: + ans = 0 + for a, b in pairwise(dirs): x, y = i + a, j + b - res += dfs(x, y, k - 1) - res %= mod - return res + ans = (ans + dfs(x, y, k - 1)) % mod + return ans mod = 10**9 + 7 + dirs = (-1, 0, 1, 0, -1) return dfs(startRow, startColumn, maxMove) ``` @@ -83,43 +93,34 @@ class Solution: ```java class Solution { - private int m; - private int n; - private int[][][] f; - private static final int[] DIRS = {-1, 0, 1, 0, -1}; - private static final int MOD = (int) 1e9 + 7; + private int m, n; + private Integer[][][] f; + private final int mod = (int) 1e9 + 7; public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { this.m = m; this.n = n; - f = new int[m + 1][n + 1][maxMove + 1]; - for (var a : f) { - for (var b : a) { - Arrays.fill(b, -1); - } - } + f = new Integer[m][n][maxMove + 1]; return dfs(startRow, startColumn, maxMove); } private int dfs(int i, int j, int k) { if (i < 0 || i >= m || j < 0 || j >= n) { - return 1; - } - if (f[i][j][k] != -1) { - return f[i][j][k]; + return k >= 0 ? 1 : 0; } - if (k == 0) { + if (k <= 0) { return 0; } - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + DIRS[t]; - int y = j + DIRS[t + 1]; - res += dfs(x, y, k - 1); - res %= MOD; + if (f[i][j][k] != null) { + return f[i][j][k]; + } + int ans = 0; + final int[] dirs = {-1, 0, 1, 0, -1}; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; } - f[i][j][k] = res; - return res; + return f[i][j][k] = ans; } } ``` @@ -129,32 +130,30 @@ class Solution { ```cpp class Solution { public: - int m; - int n; - const int mod = 1e9 + 7; - int f[51][51][51]; - int dirs[5] = {-1, 0, 1, 0, -1}; - int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { - memset(f, 0xff, sizeof(f)); - this->m = m; - this->n = n; + int f[m][n][maxMove + 1]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + const int dirs[5] = {-1, 0, 1, 0, -1}; + auto dfs = [&](this auto&& dfs, int i, int j, int k) -> int { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0; + } + if (k <= 0) { + return 0; + } + if (f[i][j][k] != -1) { + return f[i][j][k]; + } + int ans = 0; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return f[i][j][k] = ans; + }; return dfs(startRow, startColumn, maxMove); } - - int dfs(int i, int j, int k) { - if (i < 0 || i >= m || j < 0 || j >= n) return 1; - if (f[i][j][k] != -1) return f[i][j][k]; - if (k == 0) return 0; - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + dirs[t], y = j + dirs[t + 1]; - res += dfs(x, y, k - 1); - res %= mod; - } - f[i][j][k] = res; - return res; - } }; ``` @@ -162,9 +161,9 @@ public: ```go func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { - f := make([][][]int, m+1) + f := make([][][]int, m) for i := range f { - f[i] = make([][]int, n+1) + f[i] = make([][]int, n) for j := range f[i] { f[i][j] = make([]int, maxMove+1) for k := range f[i][j] { @@ -172,72 +171,67 @@ func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { } } } - var mod int = 1e9 + 7 - dirs := []int{-1, 0, 1, 0, -1} - var dfs func(i, j, k int) int + const mod int = 1e9 + 7 + var dfs func(int, int, int) int + dirs := [5]int{-1, 0, 1, 0, -1} dfs = func(i, j, k int) int { if i < 0 || i >= m || j < 0 || j >= n { - return 1 + if k >= 0 { + return 1 + } + return 0 + } + if k <= 0 { + return 0 } if f[i][j][k] != -1 { return f[i][j][k] } - if k == 0 { - return 0 - } - res := 0 - for t := 0; t < 4; t++ { - x, y := i+dirs[t], j+dirs[t+1] - res += dfs(x, y, k-1) - res %= mod + ans := 0 + for d := 0; d < 4; d++ { + x, y := i+dirs[d], j+dirs[d+1] + ans = (ans + dfs(x, y, k-1)) % mod } - f[i][j][k] = res - return res + f[i][j][k] = ans + return ans } return dfs(startRow, startColumn, maxMove) } ``` - - - - - - -### Solution 2 - - - -#### Java - -```java -class Solution { - public int findPaths(int m, int n, int N, int i, int j) { - final int MOD = (int) (1e9 + 7); - final int[] dirs = new int[] {-1, 0, 1, 0, -1}; - int[][] f = new int[m][n]; - f[i][j] = 1; - int res = 0; - for (int step = 0; step < N; ++step) { - int[][] temp = new int[m][n]; - for (int x = 0; x < m; ++x) { - for (int y = 0; y < n; ++y) { - for (int k = 0; k < 4; ++k) { - int tx = x + dirs[k], ty = y + dirs[k + 1]; - if (tx >= 0 && tx < m && ty >= 0 && ty < n) { - temp[tx][ty] += f[x][y]; - temp[tx][ty] %= MOD; - } else { - res += f[x][y]; - res %= MOD; - } - } - } - } - f = temp; +#### TypeScript + +```ts +function findPaths( + m: number, + n: number, + maxMove: number, + startRow: number, + startColumn: number, +): number { + const f = Array.from({ length: m }, () => + Array.from({ length: n }, () => Array(maxMove + 1).fill(-1)), + ); + const mod = 1000000007; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number, k: number): number => { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0 ? 1 : 0; } - return res; - } + if (k <= 0) { + return 0; + } + if (f[i][j][k] !== -1) { + return f[i][j][k]; + } + let ans = 0; + for (let d = 0; d < 4; ++d) { + const [x, y] = [i + dirs[d], j + dirs[d + 1]]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return (f[i][j][k] = ans); + }; + return dfs(startRow, startColumn, maxMove); } ``` diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution.cpp b/solution/0500-0599/0576.Out of Boundary Paths/Solution.cpp index 9ce8f94fe0a4c..f8abef968f0f2 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/Solution.cpp +++ b/solution/0500-0599/0576.Out of Boundary Paths/Solution.cpp @@ -1,29 +1,27 @@ class Solution { public: - int m; - int n; - const int mod = 1e9 + 7; - int f[51][51][51]; - int dirs[5] = {-1, 0, 1, 0, -1}; - int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { - memset(f, 0xff, sizeof(f)); - this->m = m; - this->n = n; + int f[m][n][maxMove + 1]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + const int dirs[5] = {-1, 0, 1, 0, -1}; + auto dfs = [&](this auto&& dfs, int i, int j, int k) -> int { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0; + } + if (k <= 0) { + return 0; + } + if (f[i][j][k] != -1) { + return f[i][j][k]; + } + int ans = 0; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return f[i][j][k] = ans; + }; return dfs(startRow, startColumn, maxMove); } - - int dfs(int i, int j, int k) { - if (i < 0 || i >= m || j < 0 || j >= n) return 1; - if (f[i][j][k] != -1) return f[i][j][k]; - if (k == 0) return 0; - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + dirs[t], y = j + dirs[t + 1]; - res += dfs(x, y, k - 1); - res %= mod; - } - f[i][j][k] = res; - return res; - } -}; \ No newline at end of file +}; diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution.go b/solution/0500-0599/0576.Out of Boundary Paths/Solution.go index 718a9d658191f..eaeb82491afd7 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/Solution.go +++ b/solution/0500-0599/0576.Out of Boundary Paths/Solution.go @@ -1,7 +1,7 @@ func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { - f := make([][][]int, m+1) + f := make([][][]int, m) for i := range f { - f[i] = make([][]int, n+1) + f[i] = make([][]int, n) for j := range f[i] { f[i][j] = make([]int, maxMove+1) for k := range f[i][j] { @@ -9,27 +9,29 @@ func findPaths(m int, n int, maxMove int, startRow int, startColumn int) int { } } } - var mod int = 1e9 + 7 - dirs := []int{-1, 0, 1, 0, -1} - var dfs func(i, j, k int) int + const mod int = 1e9 + 7 + var dfs func(int, int, int) int + dirs := [5]int{-1, 0, 1, 0, -1} dfs = func(i, j, k int) int { if i < 0 || i >= m || j < 0 || j >= n { - return 1 + if k >= 0 { + return 1 + } + return 0 + } + if k <= 0 { + return 0 } if f[i][j][k] != -1 { return f[i][j][k] } - if k == 0 { - return 0 - } - res := 0 - for t := 0; t < 4; t++ { - x, y := i+dirs[t], j+dirs[t+1] - res += dfs(x, y, k-1) - res %= mod + ans := 0 + for d := 0; d < 4; d++ { + x, y := i+dirs[d], j+dirs[d+1] + ans = (ans + dfs(x, y, k-1)) % mod } - f[i][j][k] = res - return res + f[i][j][k] = ans + return ans } return dfs(startRow, startColumn, maxMove) -} \ No newline at end of file +} diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution.java b/solution/0500-0599/0576.Out of Boundary Paths/Solution.java index 57bd868d23bea..c4be70e838a0b 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/Solution.java +++ b/solution/0500-0599/0576.Out of Boundary Paths/Solution.java @@ -1,40 +1,31 @@ class Solution { - private int m; - private int n; - private int[][][] f; - private static final int[] DIRS = {-1, 0, 1, 0, -1}; - private static final int MOD = (int) 1e9 + 7; + private int m, n; + private Integer[][][] f; + private final int mod = (int) 1e9 + 7; public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { this.m = m; this.n = n; - f = new int[m + 1][n + 1][maxMove + 1]; - for (var a : f) { - for (var b : a) { - Arrays.fill(b, -1); - } - } + f = new Integer[m][n][maxMove + 1]; return dfs(startRow, startColumn, maxMove); } private int dfs(int i, int j, int k) { if (i < 0 || i >= m || j < 0 || j >= n) { - return 1; - } - if (f[i][j][k] != -1) { - return f[i][j][k]; + return k >= 0 ? 1 : 0; } - if (k == 0) { + if (k <= 0) { return 0; } - int res = 0; - for (int t = 0; t < 4; ++t) { - int x = i + DIRS[t]; - int y = j + DIRS[t + 1]; - res += dfs(x, y, k - 1); - res %= MOD; + if (f[i][j][k] != null) { + return f[i][j][k]; + } + int ans = 0; + final int[] dirs = {-1, 0, 1, 0, -1}; + for (int d = 0; d < 4; ++d) { + int x = i + dirs[d], y = j + dirs[d + 1]; + ans = (ans + dfs(x, y, k - 1)) % mod; } - f[i][j][k] = res; - return res; + return f[i][j][k] = ans; } -} \ No newline at end of file +} diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution.py b/solution/0500-0599/0576.Out of Boundary Paths/Solution.py index 352d6b83f97d5..b9e0d543d0b85 100644 --- a/solution/0500-0599/0576.Out of Boundary Paths/Solution.py +++ b/solution/0500-0599/0576.Out of Boundary Paths/Solution.py @@ -3,17 +3,17 @@ def findPaths( self, m: int, n: int, maxMove: int, startRow: int, startColumn: int ) -> int: @cache - def dfs(i, j, k): - if i < 0 or j < 0 or i >= m or j >= n: - return 1 + def dfs(i: int, j: int, k: int) -> int: + if not 0 <= i < m or not 0 <= j < n: + return int(k >= 0) if k <= 0: return 0 - res = 0 - for a, b in [[-1, 0], [1, 0], [0, 1], [0, -1]]: + ans = 0 + for a, b in pairwise(dirs): x, y = i + a, j + b - res += dfs(x, y, k - 1) - res %= mod - return res + ans = (ans + dfs(x, y, k - 1)) % mod + return ans mod = 10**9 + 7 + dirs = (-1, 0, 1, 0, -1) return dfs(startRow, startColumn, maxMove) diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution.ts b/solution/0500-0599/0576.Out of Boundary Paths/Solution.ts new file mode 100644 index 0000000000000..1c762932b76bf --- /dev/null +++ b/solution/0500-0599/0576.Out of Boundary Paths/Solution.ts @@ -0,0 +1,31 @@ +function findPaths( + m: number, + n: number, + maxMove: number, + startRow: number, + startColumn: number, +): number { + const f = Array.from({ length: m }, () => + Array.from({ length: n }, () => Array(maxMove + 1).fill(-1)), + ); + const mod = 1000000007; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number, k: number): number => { + if (i < 0 || i >= m || j < 0 || j >= n) { + return k >= 0 ? 1 : 0; + } + if (k <= 0) { + return 0; + } + if (f[i][j][k] !== -1) { + return f[i][j][k]; + } + let ans = 0; + for (let d = 0; d < 4; ++d) { + const [x, y] = [i + dirs[d], j + dirs[d + 1]]; + ans = (ans + dfs(x, y, k - 1)) % mod; + } + return (f[i][j][k] = ans); + }; + return dfs(startRow, startColumn, maxMove); +} diff --git a/solution/0500-0599/0576.Out of Boundary Paths/Solution2.java b/solution/0500-0599/0576.Out of Boundary Paths/Solution2.java deleted file mode 100644 index 4d337135243e3..0000000000000 --- a/solution/0500-0599/0576.Out of Boundary Paths/Solution2.java +++ /dev/null @@ -1,28 +0,0 @@ -class Solution { - public int findPaths(int m, int n, int N, int i, int j) { - final int MOD = (int) (1e9 + 7); - final int[] dirs = new int[] {-1, 0, 1, 0, -1}; - int[][] f = new int[m][n]; - f[i][j] = 1; - int res = 0; - for (int step = 0; step < N; ++step) { - int[][] temp = new int[m][n]; - for (int x = 0; x < m; ++x) { - for (int y = 0; y < n; ++y) { - for (int k = 0; k < 4; ++k) { - int tx = x + dirs[k], ty = y + dirs[k + 1]; - if (tx >= 0 && tx < m && ty >= 0 && ty < n) { - temp[tx][ty] += f[x][y]; - temp[tx][ty] %= MOD; - } else { - res += f[x][y]; - res %= MOD; - } - } - } - } - f = temp; - } - return res; - } -} \ No newline at end of file