Array
Math
Monotonic Stack
Stack
Description
You are given an integer array nums
and a positive integer k
. Return the sum of the maximum and minimum elements of all subarrays with at most k
elements.
Example 1:
Input: nums = [1,2,3], k = 2
Output: 20
Explanation:
The subarrays of nums
with at most 2 elements are:
Subarray
Minimum
Maximum
Sum
[1]
1
1
2
[2]
2
2
4
[3]
3
3
6
[1, 2]
1
2
3
[2, 3]
2
3
5
Final Total
20
The output would be 20.
Example 2:
Input: nums = [1,-3,1], k = 2
Output: -6
Explanation:
The subarrays of nums
with at most 2 elements are:
Subarray
Minimum
Maximum
Sum
[1]
1
1
2
[-3]
-3
-3
-6
[1]
1
1
2
[1, -3]
-3
1
-2
[-3, 1]
-3
1
-2
Final Total
-6
The output would be -6.
Constraints:
1 <= nums.length <= 80000
1 <= k <= nums.length
-106 <= nums[i] <= 106
Solutions
Solution 1
Python3 Java C++ Go JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 /**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var minMaxSubarraySum = function ( nums , k ) {
const computeSum = ( nums , k , isMin ) => {
const n = nums . length ;
const prev = Array ( n ). fill ( - 1 );
const next = Array ( n ). fill ( n );
let stk = [];
if ( isMin ) {
for ( let i = 0 ; i < n ; i ++ ) {
while ( stk . length > 0 && nums [ stk [ stk . length - 1 ]] >= nums [ i ]) {
stk . pop ();
}
prev [ i ] = stk . length > 0 ? stk [ stk . length - 1 ] : - 1 ;
stk . push ( i );
}
stk = [];
for ( let i = n - 1 ; i >= 0 ; i -- ) {
while ( stk . length > 0 && nums [ stk [ stk . length - 1 ]] > nums [ i ]) {
stk . pop ();
}
next [ i ] = stk . length > 0 ? stk [ stk . length - 1 ] : n ;
stk . push ( i );
}
} else {
for ( let i = 0 ; i < n ; i ++ ) {
while ( stk . length > 0 && nums [ stk [ stk . length - 1 ]] <= nums [ i ]) {
stk . pop ();
}
prev [ i ] = stk . length > 0 ? stk [ stk . length - 1 ] : - 1 ;
stk . push ( i );
}
stk = [];
for ( let i = n - 1 ; i >= 0 ; i -- ) {
while ( stk . length > 0 && nums [ stk [ stk . length - 1 ]] < nums [ i ]) {
stk . pop ();
}
next [ i ] = stk . length > 0 ? stk [ stk . length - 1 ] : n ;
stk . push ( i );
}
}
let totalSum = 0 ;
for ( let i = 0 ; i < n ; i ++ ) {
const left = prev [ i ];
const right = next [ i ];
const a = left + 1 ;
const b = i ;
const c = i ;
const d = right - 1 ;
let start1 = Math . max ( a , i - k + 1 );
let endCandidate1 = d - k + 1 ;
let upper1 = Math . min ( b , endCandidate1 );
let sum1 = 0 ;
if ( upper1 >= start1 ) {
const termCount = upper1 - start1 + 1 ;
const first = start1 ;
const last = upper1 ;
const indexSum = ( last * ( last + 1 )) / 2 - (( first - 1 ) * first ) / 2 ;
const constantSum = ( k - i ) * termCount ;
sum1 = indexSum + constantSum ;
}
let start2 = upper1 + 1 ;
let end2 = b ;
start2 = Math . max ( start2 , a );
end2 = Math . min ( end2 , b );
let sum2 = 0 ;
if ( start2 <= end2 ) {
const count = end2 - start2 + 1 ;
const term = d - i + 1 ;
sum2 = term * count ;
}
totalSum += nums [ i ] * ( sum1 + sum2 );
}
return totalSum ;
};
const minSum = computeSum ( nums , k , true );
const maxSum = computeSum ( nums , k , false );
return minSum + maxSum ;
};
GitHub