@@ -81,16 +81,26 @@ tags:
81
81
82
82
## 解法
83
83
84
- <!-- solution:start -->
85
-
86
- ### 方法一
87
-
88
84
<!-- tabs:start -->
89
85
90
86
#### Python3
91
87
92
88
``` 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
94
104
```
95
105
96
106
#### Java
@@ -102,13 +112,187 @@ tags:
102
112
#### C++
103
113
104
114
``` 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
+ };
106
216
```
107
217
108
218
#### Go
109
219
110
220
``` 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
+ }
111
292
293
+ ans
294
+ }
295
+ }
112
296
```
113
297
114
298
<!-- tabs:end -->
0 commit comments