diff --git a/solution/0500-0599/0554.Brick Wall/README.md b/solution/0500-0599/0554.Brick Wall/README.md index 9721672166d43..76f8531a69bd9 100644 --- a/solution/0500-0599/0554.Brick Wall/README.md +++ b/solution/0500-0599/0554.Brick Wall/README.md @@ -56,7 +56,15 @@ tags: -### 方法一 +### 方法一:哈希表 + 前缀和 + +我们可以用一个哈希表 $\textit{cnt}$ 记录每一行除了最后一个砖块以外的前缀和,其中键为前缀和的值,值为该前缀和出现的次数。 + +遍历每一行,对于当前行的每一个砖块,我们将其加到当前的前缀和上,然后更新 $\textit{cnt}$。 + +最后我们遍历 $\textit{cnt}$,找出出现次数最多的前缀和,这就是穿过的砖块数量最少的情况。最后答案即为砖墙的行数减去穿过的砖块数量。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(n)$。其中 $m$ 和 $n$ 分别是砖墙的行数和砖墙的砖块数。 @@ -65,15 +73,13 @@ tags: ```python class Solution: def leastBricks(self, wall: List[List[int]]) -> int: - cnt = defaultdict(int) + cnt = Counter() for row in wall: - width = 0 - for brick in row[:-1]: - width += brick - cnt[width] += 1 - if not cnt: - return len(wall) - return len(wall) - cnt[max(cnt, key=cnt.get)] + s = 0 + for x in row[:-1]: + s += x + cnt[s] += 1 + return len(wall) - max(cnt.values(), default=0) ``` #### Java @@ -82,38 +88,79 @@ class Solution: class Solution { public int leastBricks(List> wall) { Map cnt = new HashMap<>(); - for (List row : wall) { - int width = 0; - for (int i = 0, n = row.size() - 1; i < n; i++) { - width += row.get(i); - cnt.merge(width, 1, Integer::sum); + for (var row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row.get(i); + cnt.merge(s, 1, Integer::sum); } } - int max = cnt.values().stream().max(Comparator.naturalOrder()).orElse(0); - return wall.size() - max; + int mx = 0; + for (var x : cnt.values()) { + mx = Math.max(mx, x); + } + return wall.size() - mx; } } ``` +#### C++ + +```cpp +class Solution { +public: + int leastBricks(vector>& wall) { + unordered_map cnt; + for (const auto& row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row[i]; + cnt[s]++; + } + } + int mx = 0; + for (const auto& [_, x] : cnt) { + mx = max(mx, x); + } + return wall.size() - mx; + } +}; +``` + #### Go ```go func leastBricks(wall [][]int) int { - cnt := make(map[int]int) + cnt := map[int]int{} for _, row := range wall { - width := 0 - for _, brick := range row[:len(row)-1] { - width += brick - cnt[width]++ + s := 0 + for _, x := range row[:len(row)-1] { + s += x + cnt[s]++ } } - max := 0 - for _, v := range cnt { - if v > max { - max = v - } + mx := 0 + for _, x := range cnt { + mx = max(mx, x) } - return len(wall) - max + return len(wall) - mx +} +``` + +#### TypeScript + +```ts +function leastBricks(wall: number[][]): number { + const cnt: Map = new Map(); + for (const row of wall) { + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); + } + } + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; } ``` @@ -127,17 +174,14 @@ func leastBricks(wall [][]int) int { var leastBricks = function (wall) { const cnt = new Map(); for (const row of wall) { - let width = 0; - for (let i = 0, n = row.length - 1; i < n; ++i) { - width += row[i]; - cnt.set(width, (cnt.get(width) || 0) + 1); + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); } } - let max = 0; - for (const v of cnt.values()) { - max = Math.max(max, v); - } - return wall.length - max; + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; }; ``` diff --git a/solution/0500-0599/0554.Brick Wall/README_EN.md b/solution/0500-0599/0554.Brick Wall/README_EN.md index 41253ff148ab2..b7ceb9703130e 100644 --- a/solution/0500-0599/0554.Brick Wall/README_EN.md +++ b/solution/0500-0599/0554.Brick Wall/README_EN.md @@ -56,7 +56,15 @@ tags: -### Solution 1 +### Solution 1: Hash Table + Prefix Sum + +We can use a hash table $\textit{cnt}$ to record the prefix sum of each row except for the last brick. The key is the value of the prefix sum, and the value is the number of times the prefix sum appears. + +Traverse each row, and for each brick in the current row, add it to the current prefix sum and update $\textit{cnt}$. + +Finally, we traverse $\textit{cnt}$ to find the prefix sum that appears the most times, which represents the situation where the least number of bricks are crossed. The final answer is the number of rows in the brick wall minus the number of bricks crossed. + +The time complexity is $O(m \times n)$, and the space complexity is $O(n)$. Here, $m$ and $n$ are the number of rows and the number of bricks in the brick wall, respectively. @@ -65,15 +73,13 @@ tags: ```python class Solution: def leastBricks(self, wall: List[List[int]]) -> int: - cnt = defaultdict(int) + cnt = Counter() for row in wall: - width = 0 - for brick in row[:-1]: - width += brick - cnt[width] += 1 - if not cnt: - return len(wall) - return len(wall) - cnt[max(cnt, key=cnt.get)] + s = 0 + for x in row[:-1]: + s += x + cnt[s] += 1 + return len(wall) - max(cnt.values(), default=0) ``` #### Java @@ -82,38 +88,79 @@ class Solution: class Solution { public int leastBricks(List> wall) { Map cnt = new HashMap<>(); - for (List row : wall) { - int width = 0; - for (int i = 0, n = row.size() - 1; i < n; i++) { - width += row.get(i); - cnt.merge(width, 1, Integer::sum); + for (var row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row.get(i); + cnt.merge(s, 1, Integer::sum); } } - int max = cnt.values().stream().max(Comparator.naturalOrder()).orElse(0); - return wall.size() - max; + int mx = 0; + for (var x : cnt.values()) { + mx = Math.max(mx, x); + } + return wall.size() - mx; } } ``` +#### C++ + +```cpp +class Solution { +public: + int leastBricks(vector>& wall) { + unordered_map cnt; + for (const auto& row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row[i]; + cnt[s]++; + } + } + int mx = 0; + for (const auto& [_, x] : cnt) { + mx = max(mx, x); + } + return wall.size() - mx; + } +}; +``` + #### Go ```go func leastBricks(wall [][]int) int { - cnt := make(map[int]int) + cnt := map[int]int{} for _, row := range wall { - width := 0 - for _, brick := range row[:len(row)-1] { - width += brick - cnt[width]++ + s := 0 + for _, x := range row[:len(row)-1] { + s += x + cnt[s]++ } } - max := 0 - for _, v := range cnt { - if v > max { - max = v - } + mx := 0 + for _, x := range cnt { + mx = max(mx, x) } - return len(wall) - max + return len(wall) - mx +} +``` + +#### TypeScript + +```ts +function leastBricks(wall: number[][]): number { + const cnt: Map = new Map(); + for (const row of wall) { + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); + } + } + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; } ``` @@ -127,17 +174,14 @@ func leastBricks(wall [][]int) int { var leastBricks = function (wall) { const cnt = new Map(); for (const row of wall) { - let width = 0; - for (let i = 0, n = row.length - 1; i < n; ++i) { - width += row[i]; - cnt.set(width, (cnt.get(width) || 0) + 1); + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); } } - let max = 0; - for (const v of cnt.values()) { - max = Math.max(max, v); - } - return wall.length - max; + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; }; ``` diff --git a/solution/0500-0599/0554.Brick Wall/Solution.cpp b/solution/0500-0599/0554.Brick Wall/Solution.cpp new file mode 100644 index 0000000000000..426dbdc6e49e3 --- /dev/null +++ b/solution/0500-0599/0554.Brick Wall/Solution.cpp @@ -0,0 +1,18 @@ +class Solution { +public: + int leastBricks(vector>& wall) { + unordered_map cnt; + for (const auto& row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row[i]; + cnt[s]++; + } + } + int mx = 0; + for (const auto& [_, x] : cnt) { + mx = max(mx, x); + } + return wall.size() - mx; + } +}; diff --git a/solution/0500-0599/0554.Brick Wall/Solution.go b/solution/0500-0599/0554.Brick Wall/Solution.go index a23a5f6459b94..18cee31c05524 100644 --- a/solution/0500-0599/0554.Brick Wall/Solution.go +++ b/solution/0500-0599/0554.Brick Wall/Solution.go @@ -1,17 +1,15 @@ func leastBricks(wall [][]int) int { - cnt := make(map[int]int) + cnt := map[int]int{} for _, row := range wall { - width := 0 - for _, brick := range row[:len(row)-1] { - width += brick - cnt[width]++ + s := 0 + for _, x := range row[:len(row)-1] { + s += x + cnt[s]++ } } - max := 0 - for _, v := range cnt { - if v > max { - max = v - } + mx := 0 + for _, x := range cnt { + mx = max(mx, x) } - return len(wall) - max -} \ No newline at end of file + return len(wall) - mx +} diff --git a/solution/0500-0599/0554.Brick Wall/Solution.java b/solution/0500-0599/0554.Brick Wall/Solution.java index e4447835bcbbf..f3651533b2e4b 100644 --- a/solution/0500-0599/0554.Brick Wall/Solution.java +++ b/solution/0500-0599/0554.Brick Wall/Solution.java @@ -1,14 +1,17 @@ class Solution { public int leastBricks(List> wall) { Map cnt = new HashMap<>(); - for (List row : wall) { - int width = 0; - for (int i = 0, n = row.size() - 1; i < n; i++) { - width += row.get(i); - cnt.merge(width, 1, Integer::sum); + for (var row : wall) { + int s = 0; + for (int i = 0; i + 1 < row.size(); ++i) { + s += row.get(i); + cnt.merge(s, 1, Integer::sum); } } - int max = cnt.values().stream().max(Comparator.naturalOrder()).orElse(0); - return wall.size() - max; + int mx = 0; + for (var x : cnt.values()) { + mx = Math.max(mx, x); + } + return wall.size() - mx; } -} \ No newline at end of file +} diff --git a/solution/0500-0599/0554.Brick Wall/Solution.js b/solution/0500-0599/0554.Brick Wall/Solution.js index 078f4d90b35b3..a30882bd06b41 100644 --- a/solution/0500-0599/0554.Brick Wall/Solution.js +++ b/solution/0500-0599/0554.Brick Wall/Solution.js @@ -5,15 +5,12 @@ var leastBricks = function (wall) { const cnt = new Map(); for (const row of wall) { - let width = 0; - for (let i = 0, n = row.length - 1; i < n; ++i) { - width += row[i]; - cnt.set(width, (cnt.get(width) || 0) + 1); + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); } } - let max = 0; - for (const v of cnt.values()) { - max = Math.max(max, v); - } - return wall.length - max; + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; }; diff --git a/solution/0500-0599/0554.Brick Wall/Solution.py b/solution/0500-0599/0554.Brick Wall/Solution.py index cfd160aa3d1f3..5d31c91acdb35 100644 --- a/solution/0500-0599/0554.Brick Wall/Solution.py +++ b/solution/0500-0599/0554.Brick Wall/Solution.py @@ -1,11 +1,9 @@ class Solution: def leastBricks(self, wall: List[List[int]]) -> int: - cnt = defaultdict(int) + cnt = Counter() for row in wall: - width = 0 - for brick in row[:-1]: - width += brick - cnt[width] += 1 - if not cnt: - return len(wall) - return len(wall) - cnt[max(cnt, key=cnt.get)] + s = 0 + for x in row[:-1]: + s += x + cnt[s] += 1 + return len(wall) - max(cnt.values(), default=0) diff --git a/solution/0500-0599/0554.Brick Wall/Solution.ts b/solution/0500-0599/0554.Brick Wall/Solution.ts new file mode 100644 index 0000000000000..2bb46679dc858 --- /dev/null +++ b/solution/0500-0599/0554.Brick Wall/Solution.ts @@ -0,0 +1,12 @@ +function leastBricks(wall: number[][]): number { + const cnt: Map = new Map(); + for (const row of wall) { + let s = 0; + for (let i = 0; i + 1 < row.length; ++i) { + s += row[i]; + cnt.set(s, (cnt.get(s) || 0) + 1); + } + } + const mx = Math.max(...cnt.values(), 0); + return wall.length - mx; +} 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 diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md index a6f7ec447934c..5e449996aeb1d 100644 --- a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md @@ -72,32 +72,295 @@ tags: -### 方法一 +### 方法一:动态规划 + 前后缀分解 + 枚举 + +我们考虑将序列分成两部分,前 $k$ 个元素和后 $k$ 个元素,分别计算前后缀的所有可能的异或值。 + +定义 $f[i][j][x]$ 表示前 $i$ 个元素中取 $j$ 个元素,是否存在一个子集的异或值为 $x$,定义 $g[i][j][y]$ 表示从下标 $i$ 开始取 $j$ 个元素,是否存在一个子集的异或值为 $y$。 + +考虑 $f[i][j][x]$ 的转移方程,对于第 $i$ 个元素(从 $0$ 开始),我们可以选择不取,也可以选择取,因此有: + +$$ +f[i + 1][j][x] = f[i + 1][j][x] \lor f[i][j][x] \\ +f[i + 1][j + 1][x \lor \text{nums}[i]] = f[i + 1][j + 1][x \lor \text{nums}[i]] \lor f[i][j][x] +$$ + +对于 $g[i][j][y]$ 的转移方程,同样对于第 $i$ 个元素(从 $n - 1$ 开始),我们可以选择不取,也可以选择取,因此有: + +$$ +g[i - 1][j][y] = g[i - 1][j][y] \lor g[i][j][y] \\ +g[i - 1][j + 1][y \lor \text{nums}[i - 1]] = g[i - 1][j + 1][y \lor \text{nums}[i - 1]] \lor g[i][j][y] +$$ + +最后,我们在 $[k, n - k]$ 的范围内枚举 $i$,对于每一个 $i$,我们枚举 $x$ 和 $y$,其中 $0 \leq x, y < 2^7$,如果 $f[i][k][x]$ 和 $g[i][k][y]$ 均为真,那么我们更新答案 $\text{ans} = \max(\text{ans}, x \oplus y)$。 + +时间复杂度 $O(n \times m \times k)$,空间复杂度 $O(n \times m \times k)$,其中 $n$ 为数组长度,而 $m = 2^7$。 #### Python3 ```python - +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans ``` #### Java ```java - +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; ``` #### Go ```go +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} +``` +#### TypeScript + +```ts +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +} ``` diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md index b5951471fccb3..085c5883035f8 100644 --- a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md @@ -70,32 +70,295 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming + Prefix and Suffix Decomposition + Enumeration + +We consider dividing the sequence into two parts, the first $k$ elements and the last $k$ elements, and calculate all possible XOR values for the prefixes and suffixes. + +Define $f[i][j][x]$ to represent whether there exists a subset with an XOR value of $x$ by taking $j$ elements from the first $i$ elements. Define $g[i][j][y]$ to represent whether there exists a subset with an XOR value of $y$ by taking $j$ elements starting from index $i$. + +Consider the transition equation for $f[i][j][x]$. For the $i$-th element (starting from $0$), we can choose to take it or not, so we have: + +$$ +f[i + 1][j][x] = f[i + 1][j][x] \lor f[i][j][x] \\ +f[i + 1][j + 1][x \lor \text{nums}[i]] = f[i + 1][j + 1][x \lor \text{nums}[i]] \lor f[i][j][x] +$$ + +For the transition equation of $g[i][j][y]$, similarly for the $i$-th element (starting from $n - 1$), we can choose to take it or not, so we have: + +$$ +g[i - 1][j][y] = g[i - 1][j][y] \lor g[i][j][y] \\ +g[i - 1][j + 1][y \lor \text{nums}[i - 1]] = g[i - 1][j + 1][y \lor \text{nums}[i - 1]] \lor g[i][j][y] +$$ + +Finally, we enumerate $i$ in the range $[k, n - k]$. For each $i$, we enumerate $x$ and $y$, where $0 \leq x, y < 2^7$. If both $f[i][k][x]$ and $g[i][k][y]$ are true, we update the answer $\text{ans} = \max(\text{ans}, x \oplus y)$. + +The time complexity is $O(n \times m \times k)$, and the space complexity is $O(n \times m \times k)$, where $n$ is the length of the array, and $m = 2^7$. #### Python3 ```python - +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans ``` #### Java ```java - +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; ``` #### Go ```go +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} +``` +#### TypeScript + +```ts +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +} ``` diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp new file mode 100644 index 0000000000000..bd83af7cf06c2 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp @@ -0,0 +1,51 @@ +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go new file mode 100644 index 0000000000000..a3376fde03e61 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go @@ -0,0 +1,60 @@ +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java new file mode 100644 index 0000000000000..c337b5eb5f039 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java @@ -0,0 +1,49 @@ +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py new file mode 100644 index 0000000000000..eda9a3cc48046 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py @@ -0,0 +1,28 @@ +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts new file mode 100644 index 0000000000000..953ee97ffd7dc --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts @@ -0,0 +1,52 @@ +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +}