Skip to content

Commit 9f73a5d

Browse files
author
rom.spiridonov
committed
feat: add solutions to lc problem: No.3410
1 parent bfd23a2 commit 9f73a5d

File tree

6 files changed

+572
-8
lines changed

6 files changed

+572
-8
lines changed

solution/3400-3499/3410.Maximize Subarray Sum After Removing All Occurrences of One Element/README.md

Lines changed: 190 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,26 @@ tags:
8181

8282
## 解法
8383

84-
<!-- solution:start -->
85-
86-
### 方法一
87-
8884
<!-- tabs:start -->
8985

9086
#### Python3
9187

9288
```python
93-
89+
class Solution:
90+
def maxSubarraySum(self, nums: List[int]) -> int:
91+
max_sum = nums[0]
92+
min_sum = curr_sum = acc_min = 0
93+
dp = defaultdict(int)
94+
for num in nums:
95+
curr_sum += num
96+
curr = curr_sum - acc_min
97+
if max_sum < curr: max_sum = curr
98+
if num >= 0: continue
99+
if dp[num] > min_sum: dp[num] = min_sum
100+
dp[num] += num
101+
if acc_min > dp[num]: acc_min = dp[num]
102+
if min_sum > curr_sum: min_sum = curr_sum
103+
return max_sum
94104
```
95105

96106
#### Java
@@ -102,13 +112,187 @@ tags:
102112
#### C++
103113

104114
```cpp
105-
115+
struct T {
116+
long sum;
117+
long maxSubarraySumPrefix;
118+
long maxSubarraySumSuffix;
119+
long maxSubarraySum;
120+
T() = default;
121+
T(int num)
122+
: sum(num),
123+
maxSubarraySumPrefix(num),
124+
maxSubarraySumSuffix(num),
125+
maxSubarraySum(num) {}
126+
T(long sum, long prefix, long suffix, long maxSum)
127+
: sum(sum),
128+
maxSubarraySumPrefix(prefix),
129+
maxSubarraySumSuffix(suffix),
130+
maxSubarraySum(maxSum) {}
131+
};
132+
133+
class SegmentTree {
134+
public:
135+
SegmentTree(const vector<int>& nums) : n(nums.size()), tree(nums.size() * 4) {
136+
build(nums, 0, 0, n - 1);
137+
}
138+
139+
// Updates nums[i] to val.
140+
void update(int i, int val) {
141+
update(0, 0, n - 1, i, val);
142+
}
143+
144+
long getMaxSubarraySum() const {
145+
return tree[0].maxSubarraySum;
146+
}
147+
148+
private:
149+
const int n; // the size of the input array
150+
vector<T> tree; // the segment tree
151+
152+
void build(const vector<int>& nums, int treeIndex, int lo, int hi) {
153+
if (lo == hi) {
154+
tree[treeIndex] = T(nums[lo]);
155+
return;
156+
}
157+
const int mid = (lo + hi) / 2;
158+
build(nums, 2 * treeIndex + 1, lo, mid);
159+
build(nums, 2 * treeIndex + 2, mid + 1, hi);
160+
tree[treeIndex] = merge(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]);
161+
}
162+
163+
void update(int treeIndex, int lo, int hi, int i, int val) {
164+
if (lo == hi) {
165+
tree[treeIndex] = T(val);
166+
return;
167+
}
168+
const int mid = (lo + hi) / 2;
169+
if (i <= mid)
170+
update(2 * treeIndex + 1, lo, mid, i, val);
171+
else
172+
update(2 * treeIndex + 2, mid + 1, hi, i, val);
173+
tree[treeIndex] = merge(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]);
174+
}
175+
176+
T merge(const T& left, const T& right) const {
177+
return T(
178+
left.sum + right.sum,
179+
max(left.maxSubarraySumPrefix, left.sum + right.maxSubarraySumPrefix),
180+
max(right.maxSubarraySumSuffix, right.sum + left.maxSubarraySumSuffix),
181+
max({left.maxSubarraySum, right.maxSubarraySum,
182+
left.maxSubarraySumSuffix + right.maxSubarraySumPrefix}));
183+
}
184+
};
185+
186+
class Solution {
187+
public:
188+
long long maxSubarraySum(vector<int>& nums) {
189+
const bool allPositives =
190+
ranges::all_of(nums, [](int num) { return num >= 0; });
191+
const long sum = accumulate(nums.begin(), nums.end(), 0L);
192+
if (allPositives)
193+
return sum;
194+
const int maxNum = ranges::max(nums);
195+
if (maxNum < 0)
196+
return maxNum;
197+
198+
long ans = LONG_MIN;
199+
unordered_map<int, vector<int>> numToIndices;
200+
SegmentTree tree(nums);
201+
202+
for (int i = 0; i < nums.size(); ++i)
203+
numToIndices[nums[i]].push_back(i);
204+
205+
for (const auto& [num, indices] : numToIndices) {
206+
for (const int index : indices)
207+
tree.update(index, 0);
208+
ans = max(ans, tree.getMaxSubarraySum());
209+
for (const int index : indices)
210+
tree.update(index, num);
211+
}
212+
213+
return ans;
214+
}
215+
};
106216
```
107217

108218
#### Go
109219

110220
```go
221+
func maxSubarraySum(nums []int) int64 {
222+
ans := int64(nums[0])
223+
prefix := int64(0)
224+
minPrefix := int64(0)
225+
226+
modifiedMinPrefix := int64(0)
227+
count := make(map[int]int64)
228+
minPrefixPlusRemoval := make(map[int]int64)
229+
230+
for _, num := range nums {
231+
n64 := int64(num)
232+
prefix += n64
233+
if prefix-modifiedMinPrefix > ans {
234+
ans = prefix - modifiedMinPrefix
235+
}
236+
if n64 < 0 {
237+
count[num]++
238+
prev := minPrefixPlusRemoval[num] // по умолчанию 0
239+
minPrefixPlusRemoval[num] = min(prev, minPrefix) + n64
240+
modifiedMinPrefix = min(modifiedMinPrefix, count[num]*n64)
241+
modifiedMinPrefix = min(modifiedMinPrefix, minPrefixPlusRemoval[num])
242+
}
243+
minPrefix = min(minPrefix, prefix)
244+
modifiedMinPrefix = min(modifiedMinPrefix, minPrefix)
245+
}
246+
247+
return ans
248+
}
249+
250+
func min(a, b int64) int64 {
251+
if a < b {
252+
return a
253+
}
254+
return b
255+
}
256+
```
257+
258+
#### Rust
259+
260+
```rust
261+
use std::collections::HashMap;
262+
263+
impl Solution {
264+
pub fn max_subarray_sum(nums: Vec<i32>) -> i64 {
265+
let mut ans: i64 = *nums.iter().max().unwrap() as i64;
266+
let mut prefix: i64 = 0;
267+
let mut min_prefix: i64 = 0;
268+
269+
let mut modified_min_prefix: i64 = 0;
270+
let mut count: HashMap<i32, i64> = HashMap::new();
271+
let mut min_prefix_plus_removal: HashMap<i32, i64> = HashMap::new();
272+
273+
for &num in nums.iter() {
274+
let n64 = num as i64;
275+
prefix += n64;
276+
ans = ans.max(prefix - modified_min_prefix);
277+
278+
if n64 < 0 {
279+
let entry = count.entry(num).or_insert(0);
280+
*entry += 1;
281+
282+
let prev = *min_prefix_plus_removal.get(&num).unwrap_or(&0);
283+
min_prefix_plus_removal.insert(num, prev.min(min_prefix) + n64);
284+
285+
modified_min_prefix = modified_min_prefix.min(*entry * n64);
286+
modified_min_prefix = modified_min_prefix.min(*min_prefix_plus_removal.get(&num).unwrap());
287+
}
288+
289+
min_prefix = min_prefix.min(prefix);
290+
modified_min_prefix = modified_min_prefix.min(min_prefix);
291+
}
111292

293+
ans
294+
}
295+
}
112296
```
113297

114298
<!-- tabs:end -->

0 commit comments

Comments
 (0)