From 47be7554e2a1f1f75006a17e4f121f90237a4ddd Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 31 May 2024 10:44:06 +0800 Subject: [PATCH] feat: update solutions to lc problems: No.914,915,918 --- .../0900-0999/0913.Cat and Mouse/README_EN.md | 8 +- .../README.md | 69 +++++----- .../README_EN.md | 75 ++++++----- .../Solution.cpp | 14 +-- .../Solution.go | 18 +-- .../Solution.java | 14 +-- .../Solution.py | 4 +- .../Solution.ts | 12 ++ .../README.md | 17 +-- .../README_EN.md | 27 ++-- .../Solution.cpp | 11 +- .../Solution.go | 3 +- .../Solution.java | 3 +- .../0900-0999/0916.Word Subsets/README_EN.md | 8 +- .../README.md | 108 +--------------- .../README_EN.md | 119 +++--------------- .../Solution.cpp | 18 +-- .../Solution.go | 21 ++-- .../Solution.java | 18 +-- .../Solution.py | 16 +-- .../Solution.ts | 24 ++-- .../Solution2.cpp | 16 --- .../Solution2.go | 13 -- .../Solution2.java | 15 --- .../Solution2.py | 11 -- .../Solution2.ts | 13 -- 26 files changed, 237 insertions(+), 438 deletions(-) create mode 100644 solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.ts delete mode 100644 solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.cpp delete mode 100644 solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.go delete mode 100644 solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.java delete mode 100644 solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.py delete mode 100644 solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.ts diff --git a/solution/0900-0999/0913.Cat and Mouse/README_EN.md b/solution/0900-0999/0913.Cat and Mouse/README_EN.md index 94f09b3ccbac2..da36085b522e9 100644 --- a/solution/0900-0999/0913.Cat and Mouse/README_EN.md +++ b/solution/0900-0999/0913.Cat and Mouse/README_EN.md @@ -80,7 +80,13 @@ tags: -### Solution 1 +### Solution 1: Greatest Common Divisor + +First, we use an array or hash table `cnt` to count the occurrence of each number. Only when $X$ is a divisor of the greatest common divisor of all `cnt[i]`, can it satisfy the problem's requirement. + +Therefore, we find the greatest common divisor $g$ of the occurrence of all numbers, and then check whether it is greater than or equal to $2$. + +The time complexity is $O(n \times \log M)$, and the space complexity is $O(n + \log M)$. Where $n$ and $M$ are the length of the array `deck` and the maximum value in the array `deck`, respectively. diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README.md b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README.md index 3535a73ee6119..12cca93374ca9 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README.md +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README.md @@ -69,7 +69,7 @@ tags: 因此,我们求出所有数字出现次数的最大公约数 $g$,然后判断其是否大于等于 $2$ 即可。 -时间复杂度 $O(n\log C)$,其中 $n$ 是数组 `deck` 的长度,而 $C$ 是数组 `deck` 中的最大值。 +时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n + \log M)$。其中 $n$ 和 $M$ 分别是数组 `deck` 的长度和数组 `deck` 中的最大值。 @@ -78,8 +78,8 @@ tags: ```python class Solution: def hasGroupsSizeX(self, deck: List[int]) -> bool: - vals = Counter(deck).values() - return reduce(gcd, vals) >= 2 + cnt = Counter(deck) + return reduce(gcd, cnt.values()) >= 2 ``` #### Java @@ -87,15 +87,13 @@ class Solution: ```java class Solution { public boolean hasGroupsSizeX(int[] deck) { - int[] cnt = new int[10000]; - for (int v : deck) { - ++cnt[v]; + Map cnt = new HashMap<>(); + for (int x : deck) { + cnt.merge(x, 1, Integer::sum); } - int g = -1; - for (int v : cnt) { - if (v > 0) { - g = g == -1 ? v : gcd(g, v); - } + int g = cnt.get(deck[0]); + for (int x : cnt.values()) { + g = gcd(g, x); } return g >= 2; } @@ -112,13 +110,13 @@ class Solution { class Solution { public: bool hasGroupsSizeX(vector& deck) { - int cnt[10000] = {0}; - for (int& v : deck) ++cnt[v]; - int g = -1; - for (int& v : cnt) { - if (v) { - g = g == -1 ? v : __gcd(g, v); - } + unordered_map cnt; + for (int x : deck) { + ++cnt[x]; + } + int g = cnt[deck[0]]; + for (auto& [_, x] : cnt) { + g = gcd(g, x); } return g >= 2; } @@ -129,19 +127,13 @@ public: ```go func hasGroupsSizeX(deck []int) bool { - cnt := make([]int, 10000) - for _, v := range deck { - cnt[v]++ + cnt := map[int]int{} + for _, x := range deck { + cnt[x]++ } - g := -1 - for _, v := range cnt { - if v > 0 { - if g == -1 { - g = v - } else { - g = gcd(g, v) - } - } + g := cnt[deck[0]] + for _, x := range cnt { + g = gcd(g, x) } return g >= 2 } @@ -154,6 +146,23 @@ func gcd(a, b int) int { } ``` +#### TypeScript + +```ts +function hasGroupsSizeX(deck: number[]): boolean { + const cnt: Record = {}; + for (const x of deck) { + cnt[x] = (cnt[x] || 0) + 1; + } + const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b)); + let g = cnt[deck[0]]; + for (const [_, x] of Object.entries(cnt)) { + g = gcd(g, x); + } + return g >= 2; +} +``` + diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README_EN.md b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README_EN.md index dad44bd775085..3a200c26726a6 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README_EN.md +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/README_EN.md @@ -62,7 +62,13 @@ tags: -### Solution 1 +### Solution 1: Greatest Common Divisor + +First, we use an array or hash table `cnt` to count the occurrence of each number. Only when $X$ is a divisor of the greatest common divisor of all `cnt[i]`, can it satisfy the problem's requirement. + +Therefore, we find the greatest common divisor $g$ of the occurrence of all numbers, and then check whether it is greater than or equal to $2$. + +The time complexity is $O(n \times \log M)$, and the space complexity is $O(n + \log M)$. Where $n$ and $M$ are the length of the array `deck` and the maximum value in the array `deck`, respectively. @@ -71,8 +77,8 @@ tags: ```python class Solution: def hasGroupsSizeX(self, deck: List[int]) -> bool: - vals = Counter(deck).values() - return reduce(gcd, vals) >= 2 + cnt = Counter(deck) + return reduce(gcd, cnt.values()) >= 2 ``` #### Java @@ -80,15 +86,13 @@ class Solution: ```java class Solution { public boolean hasGroupsSizeX(int[] deck) { - int[] cnt = new int[10000]; - for (int v : deck) { - ++cnt[v]; + Map cnt = new HashMap<>(); + for (int x : deck) { + cnt.merge(x, 1, Integer::sum); } - int g = -1; - for (int v : cnt) { - if (v > 0) { - g = g == -1 ? v : gcd(g, v); - } + int g = cnt.get(deck[0]); + for (int x : cnt.values()) { + g = gcd(g, x); } return g >= 2; } @@ -105,13 +109,13 @@ class Solution { class Solution { public: bool hasGroupsSizeX(vector& deck) { - int cnt[10000] = {0}; - for (int& v : deck) ++cnt[v]; - int g = -1; - for (int& v : cnt) { - if (v) { - g = g == -1 ? v : __gcd(g, v); - } + unordered_map cnt; + for (int x : deck) { + ++cnt[x]; + } + int g = cnt[deck[0]]; + for (auto& [_, x] : cnt) { + g = gcd(g, x); } return g >= 2; } @@ -122,19 +126,13 @@ public: ```go func hasGroupsSizeX(deck []int) bool { - cnt := make([]int, 10000) - for _, v := range deck { - cnt[v]++ + cnt := map[int]int{} + for _, x := range deck { + cnt[x]++ } - g := -1 - for _, v := range cnt { - if v > 0 { - if g == -1 { - g = v - } else { - g = gcd(g, v) - } - } + g := cnt[deck[0]] + for _, x := range cnt { + g = gcd(g, x) } return g >= 2 } @@ -147,6 +145,23 @@ func gcd(a, b int) int { } ``` +#### TypeScript + +```ts +function hasGroupsSizeX(deck: number[]): boolean { + const cnt: Record = {}; + for (const x of deck) { + cnt[x] = (cnt[x] || 0) + 1; + } + const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b)); + let g = cnt[deck[0]]; + for (const [_, x] of Object.entries(cnt)) { + g = gcd(g, x); + } + return g >= 2; +} +``` + diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.cpp b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.cpp index 4e3aba74883fd..c390a01fc449a 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.cpp +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.cpp @@ -1,13 +1,13 @@ class Solution { public: bool hasGroupsSizeX(vector& deck) { - int cnt[10000] = {0}; - for (int& v : deck) ++cnt[v]; - int g = -1; - for (int& v : cnt) { - if (v) { - g = g == -1 ? v : __gcd(g, v); - } + unordered_map cnt; + for (int x : deck) { + ++cnt[x]; + } + int g = cnt[deck[0]]; + for (auto& [_, x] : cnt) { + g = gcd(g, x); } return g >= 2; } diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.go b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.go index a7dce5848113d..f7ad170b95fdd 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.go +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.go @@ -1,17 +1,11 @@ func hasGroupsSizeX(deck []int) bool { - cnt := make([]int, 10000) - for _, v := range deck { - cnt[v]++ + cnt := map[int]int{} + for _, x := range deck { + cnt[x]++ } - g := -1 - for _, v := range cnt { - if v > 0 { - if g == -1 { - g = v - } else { - g = gcd(g, v) - } - } + g := cnt[deck[0]] + for _, x := range cnt { + g = gcd(g, x) } return g >= 2 } diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.java b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.java index 2218d3e29ad9d..ae73f04012738 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.java +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.java @@ -1,14 +1,12 @@ class Solution { public boolean hasGroupsSizeX(int[] deck) { - int[] cnt = new int[10000]; - for (int v : deck) { - ++cnt[v]; + Map cnt = new HashMap<>(); + for (int x : deck) { + cnt.merge(x, 1, Integer::sum); } - int g = -1; - for (int v : cnt) { - if (v > 0) { - g = g == -1 ? v : gcd(g, v); - } + int g = cnt.get(deck[0]); + for (int x : cnt.values()) { + g = gcd(g, x); } return g >= 2; } diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.py b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.py index e6577a22ec230..c45eb32f3dafc 100644 --- a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.py +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.py @@ -1,4 +1,4 @@ class Solution: def hasGroupsSizeX(self, deck: List[int]) -> bool: - vals = Counter(deck).values() - return reduce(gcd, vals) >= 2 + cnt = Counter(deck) + return reduce(gcd, cnt.values()) >= 2 diff --git a/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.ts b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.ts new file mode 100644 index 0000000000000..7013cd20089ef --- /dev/null +++ b/solution/0900-0999/0914.X of a Kind in a Deck of Cards/Solution.ts @@ -0,0 +1,12 @@ +function hasGroupsSizeX(deck: number[]): boolean { + const cnt: Record = {}; + for (const x of deck) { + cnt[x] = (cnt[x] || 0) + 1; + } + const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b)); + let g = cnt[deck[0]]; + for (const [_, x] of Object.entries(cnt)) { + g = gcd(g, x); + } + return g >= 2; +} diff --git a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README.md b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README.md index ff850de183fa3..bc7b202fc2884 100644 --- a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README.md +++ b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README.md @@ -102,14 +102,13 @@ class Solution { mi[i] = Math.min(nums[i], mi[i + 1]); } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = Math.max(mx, v); if (mx <= mi[i]) { return i; } } - return 0; } } ``` @@ -122,14 +121,17 @@ public: int partitionDisjoint(vector& nums) { int n = nums.size(); vector mi(n + 1, INT_MAX); - for (int i = n - 1; ~i; --i) mi[i] = min(nums[i], mi[i + 1]); + for (int i = n - 1; ~i; --i) { + mi[i] = min(nums[i], mi[i + 1]); + } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = max(mx, v); - if (mx <= mi[i]) return i; + if (mx <= mi[i]) { + return i; + } } - return 0; } }; ``` @@ -145,14 +147,13 @@ func partitionDisjoint(nums []int) int { mi[i] = min(nums[i], mi[i+1]) } mx := 0 - for i := 1; i <= n; i++ { + for i := 1; ; i++ { v := nums[i-1] mx = max(mx, v) if mx <= mi[i] { return i } } - return 0 } ``` diff --git a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README_EN.md b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README_EN.md index 0bdb63f7cce11..120b0fbb48fb5 100644 --- a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README_EN.md +++ b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/README_EN.md @@ -60,7 +60,15 @@ tags: -### Solution 1 +### Solution 1: Prefix Maximum + Suffix Minimum + +To satisfy the requirements of the problem after partitioning into two subarrays, we need to ensure that the "maximum value of the array prefix" is less than or equal to the "minimum value of the array suffix". + +Therefore, we can first preprocess the minimum value of the array suffix and record it in the `mi` array. + +Then, we traverse the array from front to back, maintaining the maximum value `mx` of the array prefix. When we traverse to a certain position, if the maximum value of the array prefix is less than or equal to the minimum value of the array suffix, then the current position is the dividing point of the partition, and we can return it directly. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array `nums`. @@ -92,14 +100,13 @@ class Solution { mi[i] = Math.min(nums[i], mi[i + 1]); } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = Math.max(mx, v); if (mx <= mi[i]) { return i; } } - return 0; } } ``` @@ -112,14 +119,17 @@ public: int partitionDisjoint(vector& nums) { int n = nums.size(); vector mi(n + 1, INT_MAX); - for (int i = n - 1; ~i; --i) mi[i] = min(nums[i], mi[i + 1]); + for (int i = n - 1; ~i; --i) { + mi[i] = min(nums[i], mi[i + 1]); + } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = max(mx, v); - if (mx <= mi[i]) return i; + if (mx <= mi[i]) { + return i; + } } - return 0; } }; ``` @@ -135,14 +145,13 @@ func partitionDisjoint(nums []int) int { mi[i] = min(nums[i], mi[i+1]) } mx := 0 - for i := 1; i <= n; i++ { + for i := 1; ; i++ { v := nums[i-1] mx = max(mx, v) if mx <= mi[i] { return i } } - return 0 } ``` diff --git a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.cpp b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.cpp index c005f2d7c77b1..36704be0c53bb 100644 --- a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.cpp +++ b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.cpp @@ -3,13 +3,16 @@ class Solution { int partitionDisjoint(vector& nums) { int n = nums.size(); vector mi(n + 1, INT_MAX); - for (int i = n - 1; ~i; --i) mi[i] = min(nums[i], mi[i + 1]); + for (int i = n - 1; ~i; --i) { + mi[i] = min(nums[i], mi[i + 1]); + } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = max(mx, v); - if (mx <= mi[i]) return i; + if (mx <= mi[i]) { + return i; + } } - return 0; } }; \ No newline at end of file diff --git a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.go b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.go index 8091bf0727bdf..e1a31db81d137 100644 --- a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.go +++ b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.go @@ -6,12 +6,11 @@ func partitionDisjoint(nums []int) int { mi[i] = min(nums[i], mi[i+1]) } mx := 0 - for i := 1; i <= n; i++ { + for i := 1; ; i++ { v := nums[i-1] mx = max(mx, v) if mx <= mi[i] { return i } } - return 0 } \ No newline at end of file diff --git a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.java b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.java index ae90122d31b8d..eeea61888f44e 100644 --- a/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.java +++ b/solution/0900-0999/0915.Partition Array into Disjoint Intervals/Solution.java @@ -7,13 +7,12 @@ public int partitionDisjoint(int[] nums) { mi[i] = Math.min(nums[i], mi[i + 1]); } int mx = 0; - for (int i = 1; i <= n; ++i) { + for (int i = 1;; ++i) { int v = nums[i - 1]; mx = Math.max(mx, v); if (mx <= mi[i]) { return i; } } - return 0; } } \ No newline at end of file diff --git a/solution/0900-0999/0916.Word Subsets/README_EN.md b/solution/0900-0999/0916.Word Subsets/README_EN.md index 9c359b8baa13b..74f89848a05c4 100644 --- a/solution/0900-0999/0916.Word Subsets/README_EN.md +++ b/solution/0900-0999/0916.Word Subsets/README_EN.md @@ -61,7 +61,13 @@ tags: -### Solution 1 +### Solution 1: Counting + +Traverse each word `b` in `words2`, count the maximum occurrence of each letter, and record it as `cnt`. + +Then traverse each word `a` in `words1`, count the occurrence of each letter, and record it as `t`. If the occurrence of each letter in `cnt` is not greater than the occurrence in `t`, then `a` is a universal word, and add it to the answer. + +The time complexity is $O(L)$, where $L$ is the sum of the lengths of all words in `words1` and `words2`. diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/README.md b/solution/0900-0999/0918.Maximum Sum Circular Subarray/README.md index e771ee0a38a92..26397242bfaf5 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/README.md +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/README.md @@ -99,109 +99,6 @@ tags: #### Python3 -```python -class Solution: - def maxSubarraySumCircular(self, nums: List[int]) -> int: - s1 = s2 = f1 = f2 = nums[0] - for num in nums[1:]: - f1 = num + max(f1, 0) - f2 = num + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) - return s1 if s1 <= 0 else max(s1, sum(nums) - s2) -``` - -#### Java - -```java -class Solution { - public int maxSubarraySumCircular(int[] nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.length; ++i) { - total += nums[i]; - f1 = nums[i] + Math.max(f1, 0); - f2 = nums[i] + Math.min(f2, 0); - s1 = Math.max(s1, f1); - s2 = Math.min(s2, f2); - } - return s1 > 0 ? Math.max(s1, total - s2) : s1; - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int maxSubarraySumCircular(vector& nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.size(); ++i) { - total += nums[i]; - f1 = nums[i] + max(f1, 0); - f2 = nums[i] + min(f2, 0); - s1 = max(s1, f1); - s2 = min(s2, f2); - } - return s1 > 0 ? max(s1, total - s2) : s1; - } -}; -``` - -#### Go - -```go -func maxSubarraySumCircular(nums []int) int { - s1, s2, f1, f2, total := nums[0], nums[0], nums[0], nums[0], nums[0] - for i := 1; i < len(nums); i++ { - total += nums[i] - f1 = nums[i] + max(f1, 0) - f2 = nums[i] + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) - } - if s1 <= 0 { - return s1 - } - return max(s1, total-s2) -} -``` - -#### TypeScript - -```ts -function maxSubarraySumCircular(nums: number[]): number { - let pre1 = nums[0], - pre2 = nums[0]; - let ans1 = nums[0], - ans2 = nums[0]; - let sum = nums[0]; - - for (let i = 1; i < nums.length; ++i) { - let cur = nums[i]; - sum += cur; - pre1 = Math.max(pre1 + cur, cur); - ans1 = Math.max(pre1, ans1); - - pre2 = Math.min(pre2 + cur, cur); - ans2 = Math.min(pre2, ans2); - } - return ans1 > 0 ? Math.max(ans1, sum - ans2) : ans1; -} -``` - - - - - - - -### 方法二 - - - -#### Python3 - ```python class Solution: def maxSubarraySumCircular(self, nums: List[int]) -> int: @@ -279,9 +176,8 @@ func maxSubarraySumCircular(nums []int) int { ```ts function maxSubarraySumCircular(nums: number[]): number { - const inf = 1 << 30; - let [pmi, pmx] = [0, -inf]; - let [ans, s, smi] = [-inf, 0, inf]; + let [pmi, pmx] = [0, -Infinity]; + let [ans, s, smi] = [-Infinity, 0, Infinity]; for (const x of nums) { s += x; ans = Math.max(ans, s - pmi); diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/README_EN.md b/solution/0900-0999/0918.Maximum Sum Circular Subarray/README_EN.md index f836ef872bfbf..61542291046cb 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/README_EN.md +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/README_EN.md @@ -66,110 +66,32 @@ tags: -### Solution 1 +### Solution 1: Maintain Prefix Maximum - - -#### Python3 - -```python -class Solution: - def maxSubarraySumCircular(self, nums: List[int]) -> int: - s1 = s2 = f1 = f2 = nums[0] - for num in nums[1:]: - f1 = num + max(f1, 0) - f2 = num + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) - return s1 if s1 <= 0 else max(s1, sum(nums) - s2) -``` - -#### Java - -```java -class Solution { - public int maxSubarraySumCircular(int[] nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.length; ++i) { - total += nums[i]; - f1 = nums[i] + Math.max(f1, 0); - f2 = nums[i] + Math.min(f2, 0); - s1 = Math.max(s1, f1); - s2 = Math.min(s2, f2); - } - return s1 > 0 ? Math.max(s1, total - s2) : s1; - } -} -``` - -#### C++ - -```cpp -class Solution { -public: - int maxSubarraySumCircular(vector& nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.size(); ++i) { - total += nums[i]; - f1 = nums[i] + max(f1, 0); - f2 = nums[i] + min(f2, 0); - s1 = max(s1, f1); - s2 = min(s2, f2); - } - return s1 > 0 ? max(s1, total - s2) : s1; - } -}; -``` +The maximum sum of a circular subarray can be divided into two cases: -#### Go +- Case 1: The subarray with the maximum sum does not include the circular part, which is the ordinary maximum subarray sum; +- Case 2: The subarray with the maximum sum includes the circular part, which can be transformed into: the total sum of the array minus the minimum subarray sum. -```go -func maxSubarraySumCircular(nums []int) int { - s1, s2, f1, f2, total := nums[0], nums[0], nums[0], nums[0], nums[0] - for i := 1; i < len(nums); i++ { - total += nums[i] - f1 = nums[i] + max(f1, 0) - f2 = nums[i] + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) - } - if s1 <= 0 { - return s1 - } - return max(s1, total-s2) -} -``` +Therefore, we maintain the following variables: -#### TypeScript +- The minimum prefix sum $pmi$, initially $0$; +- The maximum prefix sum $pmx$, initially $-\infty$; +- The prefix sum $s$, initially $0$; +- The minimum subarray sum $smi$, initially $\infty$; +- The answer $ans$, initially $-\infty$. -```ts -function maxSubarraySumCircular(nums: number[]): number { - let pre1 = nums[0], - pre2 = nums[0]; - let ans1 = nums[0], - ans2 = nums[0]; - let sum = nums[0]; - - for (let i = 1; i < nums.length; ++i) { - let cur = nums[i]; - sum += cur; - pre1 = Math.max(pre1 + cur, cur); - ans1 = Math.max(pre1, ans1); - - pre2 = Math.min(pre2 + cur, cur); - ans2 = Math.min(pre2, ans2); - } - return ans1 > 0 ? Math.max(ans1, sum - ans2) : ans1; -} -``` +Next, we only need to traverse the array $nums$. For the current element $x$ we are traversing, we perform the following update operations: - +- Update the prefix sum $s = s + x$; +- Update the answer $ans = \max(ans, s - pmi)$, which is the answer for Case 1 (the prefix sum $s$ minus the minimum prefix sum $pmi$ can give the maximum subarray sum); +- Update $smi = \min(smi, s - pmx)$, which is the minimum subarray sum for Case 2; +- Update $pmi = \min(pmi, s)$, which is the minimum prefix sum; +- Update $pmx = \max(pmx, s)$, which is the maximum prefix sum. - - - +After the traversal, we return the maximum value of $ans$ and $s - smi$ as the answer. -### Solution 2 +The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. @@ -252,9 +174,8 @@ func maxSubarraySumCircular(nums []int) int { ```ts function maxSubarraySumCircular(nums: number[]): number { - const inf = 1 << 30; - let [pmi, pmx] = [0, -inf]; - let [ans, s, smi] = [-inf, 0, inf]; + let [pmi, pmx] = [0, -Infinity]; + let [ans, s, smi] = [-Infinity, 0, Infinity]; for (const x of nums) { s += x; ans = Math.max(ans, s - pmi); diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.cpp b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.cpp index e887e05775157..36ad73af9cace 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.cpp +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.cpp @@ -1,14 +1,16 @@ class Solution { public: int maxSubarraySumCircular(vector& nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.size(); ++i) { - total += nums[i]; - f1 = nums[i] + max(f1, 0); - f2 = nums[i] + min(f2, 0); - s1 = max(s1, f1); - s2 = min(s2, f2); + const int inf = 1 << 30; + int pmi = 0, pmx = -inf; + int ans = -inf, s = 0, smi = inf; + for (int x : nums) { + s += x; + ans = max(ans, s - pmi); + smi = min(smi, s - pmx); + pmi = min(pmi, s); + pmx = max(pmx, s); } - return s1 > 0 ? max(s1, total - s2) : s1; + return max(ans, s - smi); } }; \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.go b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.go index dbc58caf2341e..2d9b9748db0cb 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.go +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.go @@ -1,14 +1,13 @@ func maxSubarraySumCircular(nums []int) int { - s1, s2, f1, f2, total := nums[0], nums[0], nums[0], nums[0], nums[0] - for i := 1; i < len(nums); i++ { - total += nums[i] - f1 = nums[i] + max(f1, 0) - f2 = nums[i] + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) + const inf = 1 << 30 + pmi, pmx := 0, -inf + ans, s, smi := -inf, 0, inf + for _, x := range nums { + s += x + ans = max(ans, s-pmi) + smi = min(smi, s-pmx) + pmi = min(pmi, s) + pmx = max(pmx, s) } - if s1 <= 0 { - return s1 - } - return max(s1, total-s2) + return max(ans, s-smi) } \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.java b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.java index 342745420eaa9..c3b4c1c9d4ca0 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.java +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.java @@ -1,13 +1,15 @@ class Solution { public int maxSubarraySumCircular(int[] nums) { - int s1 = nums[0], s2 = nums[0], f1 = nums[0], f2 = nums[0], total = nums[0]; - for (int i = 1; i < nums.length; ++i) { - total += nums[i]; - f1 = nums[i] + Math.max(f1, 0); - f2 = nums[i] + Math.min(f2, 0); - s1 = Math.max(s1, f1); - s2 = Math.min(s2, f2); + final int inf = 1 << 30; + int pmi = 0, pmx = -inf; + int ans = -inf, s = 0, smi = inf; + for (int x : nums) { + s += x; + ans = Math.max(ans, s - pmi); + smi = Math.min(smi, s - pmx); + pmi = Math.min(pmi, s); + pmx = Math.max(pmx, s); } - return s1 > 0 ? Math.max(s1, total - s2) : s1; + return Math.max(ans, s - smi); } } \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.py b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.py index 798c6e5ec3687..59161e8c69e64 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.py +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.py @@ -1,9 +1,11 @@ class Solution: def maxSubarraySumCircular(self, nums: List[int]) -> int: - s1 = s2 = f1 = f2 = nums[0] - for num in nums[1:]: - f1 = num + max(f1, 0) - f2 = num + min(f2, 0) - s1 = max(s1, f1) - s2 = min(s2, f2) - return s1 if s1 <= 0 else max(s1, sum(nums) - s2) + pmi, pmx = 0, -inf + ans, s, smi = -inf, 0, inf + for x in nums: + s += x + ans = max(ans, s - pmi) + smi = min(smi, s - pmx) + pmi = min(pmi, s) + pmx = max(pmx, s) + return max(ans, s - smi) diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.ts b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.ts index cbd7dd7b9ef24..ac68bad05ebcf 100644 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.ts +++ b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution.ts @@ -1,18 +1,12 @@ function maxSubarraySumCircular(nums: number[]): number { - let pre1 = nums[0], - pre2 = nums[0]; - let ans1 = nums[0], - ans2 = nums[0]; - let sum = nums[0]; - - for (let i = 1; i < nums.length; ++i) { - let cur = nums[i]; - sum += cur; - pre1 = Math.max(pre1 + cur, cur); - ans1 = Math.max(pre1, ans1); - - pre2 = Math.min(pre2 + cur, cur); - ans2 = Math.min(pre2, ans2); + let [pmi, pmx] = [0, -Infinity]; + let [ans, s, smi] = [-Infinity, 0, Infinity]; + for (const x of nums) { + s += x; + ans = Math.max(ans, s - pmi); + smi = Math.min(smi, s - pmx); + pmi = Math.min(pmi, s); + pmx = Math.max(pmx, s); } - return ans1 > 0 ? Math.max(ans1, sum - ans2) : ans1; + return Math.max(ans, s - smi); } diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.cpp b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.cpp deleted file mode 100644 index 36ad73af9cace..0000000000000 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.cpp +++ /dev/null @@ -1,16 +0,0 @@ -class Solution { -public: - int maxSubarraySumCircular(vector& nums) { - const int inf = 1 << 30; - int pmi = 0, pmx = -inf; - int ans = -inf, s = 0, smi = inf; - for (int x : nums) { - s += x; - ans = max(ans, s - pmi); - smi = min(smi, s - pmx); - pmi = min(pmi, s); - pmx = max(pmx, s); - } - return max(ans, s - smi); - } -}; \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.go b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.go deleted file mode 100644 index 2d9b9748db0cb..0000000000000 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.go +++ /dev/null @@ -1,13 +0,0 @@ -func maxSubarraySumCircular(nums []int) int { - const inf = 1 << 30 - pmi, pmx := 0, -inf - ans, s, smi := -inf, 0, inf - for _, x := range nums { - s += x - ans = max(ans, s-pmi) - smi = min(smi, s-pmx) - pmi = min(pmi, s) - pmx = max(pmx, s) - } - return max(ans, s-smi) -} \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.java b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.java deleted file mode 100644 index c3b4c1c9d4ca0..0000000000000 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.java +++ /dev/null @@ -1,15 +0,0 @@ -class Solution { - public int maxSubarraySumCircular(int[] nums) { - final int inf = 1 << 30; - int pmi = 0, pmx = -inf; - int ans = -inf, s = 0, smi = inf; - for (int x : nums) { - s += x; - ans = Math.max(ans, s - pmi); - smi = Math.min(smi, s - pmx); - pmi = Math.min(pmi, s); - pmx = Math.max(pmx, s); - } - return Math.max(ans, s - smi); - } -} \ No newline at end of file diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.py b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.py deleted file mode 100644 index 59161e8c69e64..0000000000000 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.py +++ /dev/null @@ -1,11 +0,0 @@ -class Solution: - def maxSubarraySumCircular(self, nums: List[int]) -> int: - pmi, pmx = 0, -inf - ans, s, smi = -inf, 0, inf - for x in nums: - s += x - ans = max(ans, s - pmi) - smi = min(smi, s - pmx) - pmi = min(pmi, s) - pmx = max(pmx, s) - return max(ans, s - smi) diff --git a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.ts b/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.ts deleted file mode 100644 index 632003cacf568..0000000000000 --- a/solution/0900-0999/0918.Maximum Sum Circular Subarray/Solution2.ts +++ /dev/null @@ -1,13 +0,0 @@ -function maxSubarraySumCircular(nums: number[]): number { - const inf = 1 << 30; - let [pmi, pmx] = [0, -inf]; - let [ans, s, smi] = [-inf, 0, inf]; - for (const x of nums) { - s += x; - ans = Math.max(ans, s - pmi); - smi = Math.min(smi, s - pmx); - pmi = Math.min(pmi, s); - pmx = Math.max(pmx, s); - } - return Math.max(ans, s - smi); -}