@@ -87,32 +87,343 @@ tags:
8787
8888<!-- solution:start -->
8989
90- ### 方法一
90+ ### 方法一:分组循环
91+
92+ 我们可以遍历数组,寻找所有可能的极大三段式子数组,从而计算其和并更新最大值。
93+
94+ 我们定义一个指针 $i$,初始时 $i = 0$,表示当前指向数组的第一个元素。我们将 $i$ 向右移动,直到找到第一个不满足严格递增的元素,即 $nums[ i-1] \geq nums[ i] $。如果此时 $i = l + 1$,说明这一段只有一个元素,无法形成递增序列,因此继续下一个循环。
95+
96+ 接下来,我们定义指针 $p$,表示当前递增段的结束位置。然后找出第二段严格递减的部分,如果这一段只有一个元素或者到达数组末尾,或者出现相等的元素,则继续下一个循环。
97+
98+ 然后我们定义指针 $q$,表示当前递减段的结束位置。接着找出第三段严格递增的部分,这时,我们就找到了一个极大的三段式子数组。那么这个三段式子数组的最大和,由以下几个部分组成:
99+
100+ - 下标范围 $[ p-2,..,q+1] $ 的元素之和
101+ - 从 $p-3$ 向左扩展的最大递增子数组之和,如果不存在则为 0
102+ - 从 $q+2$ 向右扩展的最大递增子数组之和,如果不存在则为 0。
103+
104+ 我们计算出这个三段式子数组的和后,更新答案。然后将指针 $i$ 移动到 $q$ 位置,这是因为第三段的递增部分可以作为下一次循环的第一段递增部分。
105+
106+ 遍历结束后,返回答案即可。
107+
108+ 时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$,只使用了常数级别的额外空间。
91109
92110<!-- tabs:start -->
93111
94112#### Python3
95113
96114``` python
97-
115+ class Solution :
116+ def maxSumTrionic (self , nums : List[int ]) -> int :
117+ n = len (nums)
118+ i = 0
119+ ans = - inf
120+ while i < n:
121+ l = i
122+ i += 1
123+ while i < n and nums[i - 1 ] < nums[i]:
124+ i += 1
125+ if i == l + 1 :
126+ continue
127+
128+ p = i - 1
129+ s = nums[p - 1 ] + nums[p]
130+ while i < n and nums[i - 1 ] > nums[i]:
131+ s += nums[i]
132+ i += 1
133+ if i == p + 1 or i == n or nums[i - 1 ] == nums[i]:
134+ continue
135+
136+ q = i - 1
137+ s += nums[i]
138+ i += 1
139+ mx = t = 0
140+ while i < n and nums[i - 1 ] < nums[i]:
141+ t += nums[i]
142+ i += 1
143+ mx = max (mx, t)
144+ s += mx
145+
146+ mx = t = 0
147+ for j in range (p - 2 , l - 1 , - 1 ):
148+ t += nums[j]
149+ mx = max (mx, t)
150+ s += mx
151+
152+ ans = max (ans, s)
153+ i = q
154+ return ans
98155```
99156
100157#### Java
101158
102159``` java
103-
160+ class Solution {
161+ public long maxSumTrionic (int [] nums ) {
162+ int n = nums. length;
163+ int i = 0 ;
164+ long ans = Long . MIN_VALUE ;
165+ while (i < n) {
166+ int l = i;
167+ i += 1 ;
168+ while (i < n && nums[i - 1 ] < nums[i]) {
169+ i += 1 ;
170+ }
171+ if (i == l + 1 ) {
172+ continue ;
173+ }
174+
175+ int p = i - 1 ;
176+ long s = nums[p - 1 ] + nums[p];
177+ while (i < n && nums[i - 1 ] > nums[i]) {
178+ s += nums[i];
179+ i += 1 ;
180+ }
181+ if (i == p + 1 || i == n || nums[i - 1 ] == nums[i]) {
182+ continue ;
183+ }
184+
185+ int q = i - 1 ;
186+ s += nums[i];
187+ i += 1 ;
188+ long mx = 0 , t = 0 ;
189+ while (i < n && nums[i - 1 ] < nums[i]) {
190+ t += nums[i];
191+ i += 1 ;
192+ mx = Math . max(mx, t);
193+ }
194+ s += mx;
195+
196+ mx = 0 ;
197+ t = 0 ;
198+ for (int j = p - 2 ; j >= l; j-- ) {
199+ t += nums[j];
200+ mx = Math . max(mx, t);
201+ }
202+ s += mx;
203+
204+ ans = Math . max(ans, s);
205+ i = q;
206+ }
207+ return ans;
208+ }
209+ }
104210```
105211
106212#### C++
107213
108214``` cpp
109-
215+ class Solution {
216+ public:
217+ long long maxSumTrionic(vector<int >& nums) {
218+ int n = nums.size();
219+ int i = 0;
220+ long long ans = LLONG_MIN;
221+ while (i < n) {
222+ int l = i;
223+ i += 1;
224+ while (i < n && nums[ i - 1] < nums[ i] ) {
225+ i += 1;
226+ }
227+ if (i == l + 1) {
228+ continue;
229+ }
230+
231+ int p = i - 1;
232+ long long s = nums[p - 1] + nums[p];
233+ while (i < n && nums[i - 1] > nums[i]) {
234+ s += nums[i];
235+ i += 1;
236+ }
237+ if (i == p + 1 || i == n || nums[i - 1 ] == nums[i]) {
238+ continue;
239+ }
240+
241+ int q = i - 1;
242+ s += nums[i];
243+ i += 1;
244+ long long mx = 0, t = 0;
245+ while (i < n && nums[i - 1] < nums[i]) {
246+ t += nums[i];
247+ i += 1;
248+ mx = max(mx, t);
249+ }
250+ s += mx;
251+
252+ mx = 0, t = 0;
253+ for (int j = p - 2; j >= l; j--) {
254+ t += nums[j];
255+ mx = max(mx, t);
256+ }
257+ s += mx;
258+
259+ ans = max(ans, s);
260+ i = q;
261+ }
262+ return ans;
263+ }
264+ };
110265```
111266
112267#### Go
113268
114269``` go
270+ func maxSumTrionic (nums []int ) int64 {
271+ n := len (nums)
272+ i := 0
273+ ans := int64 (math.MinInt64 )
274+ for i < n {
275+ l := i
276+ for i++; i < n && nums[i-1 ] < nums[i]; {
277+ i++
278+ }
279+ if i == l+1 {
280+ continue
281+ }
282+
283+ p := i - 1
284+ s := int64 (nums[p-1 ]) + int64 (nums[p])
285+ for i < n && nums[i-1 ] > nums[i] {
286+ s += int64 (nums[i])
287+ i++
288+ }
289+ if i == p+1 || i == n || nums[i-1 ] == nums[i] {
290+ continue
291+ }
292+
293+ q := i - 1
294+ s += int64 (nums[i])
295+ i++
296+ var mx , t int64
297+ for i < n && nums[i-1 ] < nums[i] {
298+ t += int64 (nums[i])
299+ i++
300+ mx = max (mx, t)
301+ }
302+ s += mx
303+
304+ mx, t = 0 , 0
305+ for j := p - 2 ; j >= l; j-- {
306+ t += int64 (nums[j])
307+ mx = max (mx, t)
308+ }
309+ s += mx
310+
311+ ans = max (ans, s)
312+ i = q
313+ }
314+ return ans
315+ }
316+ ```
317+
318+ #### TypeScript
319+
320+ ``` ts
321+ function maxSumTrionic(nums : number []): number {
322+ const n = nums .length ;
323+ let i = 0 ;
324+ let ans = - Infinity ;
325+
326+ while (i < n ) {
327+ const l = i ;
328+ i += 1 ;
329+
330+ while (i < n && nums [i - 1 ] < nums [i ]) i += 1 ;
331+ if (i === l + 1 ) continue ;
332+
333+ const p = i - 1 ;
334+ let s = nums [p - 1 ] + nums [p ];
335+
336+ while (i < n && nums [i - 1 ] > nums [i ]) {
337+ s += nums [i ];
338+ i += 1 ;
339+ }
340+ if (i === p + 1 || i === n || nums [i - 1 ] === nums [i ]) continue ;
341+
342+ const q = i - 1 ;
343+ s += nums [i ];
344+ i += 1 ;
345+
346+ let mx = 0 ,
347+ t = 0 ;
348+ while (i < n && nums [i - 1 ] < nums [i ]) {
349+ t += nums [i ];
350+ i += 1 ;
351+ mx = Math .max (mx , t );
352+ }
353+ s += mx ;
354+
355+ mx = 0 ;
356+ t = 0 ;
357+ for (let j = p - 2 ; j >= l ; j -- ) {
358+ t += nums [j ];
359+ mx = Math .max (mx , t );
360+ }
361+ s += mx ;
362+
363+ ans = Math .max (ans , s );
364+ i = q ;
365+ }
366+
367+ return ans ;
368+ }
369+ ```
115370
371+ #### Rust
372+
373+ ``` rust
374+ impl Solution {
375+ pub fn max_sum_trionic (nums : Vec <i32 >) -> i64 {
376+ let n = nums . len ();
377+ let mut i = 0 ;
378+ let mut ans = i64 :: MIN ;
379+ while i < n {
380+ let l = i ;
381+ i += 1 ;
382+ while i < n && nums [i - 1 ] < nums [i ] {
383+ i += 1 ;
384+ }
385+ if i == l + 1 {
386+ continue ;
387+ }
388+
389+ let p = i - 1 ;
390+ let mut s = nums [p - 1 ] as i64 + nums [p ] as i64 ;
391+ while i < n && nums [i - 1 ] > nums [i ] {
392+ s += nums [i ] as i64 ;
393+ i += 1 ;
394+ }
395+ if i == p + 1 || i == n || nums [i - 1 ] == nums [i ] {
396+ continue ;
397+ }
398+
399+ let q = i - 1 ;
400+ s += nums [i ] as i64 ;
401+ i += 1 ;
402+ let mut mx = 0i64 ;
403+ let mut t = 0i64 ;
404+ while i < n && nums [i - 1 ] < nums [i ] {
405+ t += nums [i ] as i64 ;
406+ i += 1 ;
407+ mx = mx . max (t );
408+ }
409+ s += mx ;
410+
411+ mx = 0 ;
412+ t = 0 ;
413+ let mut j = p as isize - 2 ;
414+ while j >= l as isize {
415+ t += nums [j as usize ] as i64 ;
416+ mx = mx . max (t );
417+ j -= 1 ;
418+ }
419+ s += mx ;
420+
421+ ans = ans . max (s );
422+ i = q ;
423+ }
424+ ans
425+ }
426+ }
116427```
117428
118429<!-- tabs:end -->
0 commit comments