Reversing a subarray can only affect the edges of the subarray. The best gain is achieved by maximizing the difference at the subarray’s new edges. We can try all possible subarrays that start or end at the array’s ends, and also consider the best possible gain by swapping the two edges in the middle.
First, compute the original value. Then, for each possible subarray, calculate the gain if we reverse it. The best gain is either by reversing a subarray that starts or ends at the array’s ends, or by maximizing the difference between the min and max of adjacent pairs. We track the minimum and maximum of min(nums[i], nums[i+1]) and max(nums[i], nums[i+1]) for all i, and use them to compute the best possible gain.
#include<vector>#include<algorithm>usingnamespace std;
classSolution {
public:int maxValueAfterReverse(vector<int>& nums) {
int n = nums.size();
int base =0;
for (int i =0; i < n-1; ++i) base += abs(nums[i] - nums[i+1]);
int res = base;
int mx =0, mn =1e9;
for (int i =1; i < n-1; ++i) {
mx = max(mx, min(nums[i], nums[i+1]));
mn = min(mn, max(nums[i], nums[i+1]));
}
if (mx < mn) res = max(res, base +2*(mn - mx));
for (int i =1; i < n-1; ++i) {
res = max(res, base + abs(nums[0] - nums[i+1]) - abs(nums[i] - nums[i+1]));
res = max(res, base + abs(nums[n-1] - nums[i-1]) - abs(nums[i] - nums[i-1]));
}
return res;
}
};
import"math"funcmaxValueAfterReverse(nums []int) int {
n:= len(nums)
base:=0fori:=0; i < n-1; i++ {
base+=abs(nums[i] -nums[i+1])
}
res:=basemx, mn:=0, math.MaxInt32fori:=1; i < n-1; i++ {
mx = max(mx, min(nums[i], nums[i+1]))
mn = min(mn, max(nums[i], nums[i+1]))
}
ifmx < mn {
res = max(res, base+2*(mn-mx))
}
fori:=1; i < n-1; i++ {
res = max(res, base+abs(nums[0]-nums[i+1])-abs(nums[i]-nums[i+1]))
res = max(res, base+abs(nums[n-1]-nums[i-1])-abs(nums[i]-nums[i-1]))
}
returnres}
funcabs(xint) int { ifx < 0 { return-x }; returnx }
func min(a, bint) int { ifa < b { returna }; returnb }
func max(a, bint) int { ifa > b { returna }; returnb }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
publicintmaxValueAfterReverse(int[] nums) {
int n = nums.length, base = 0;
for (int i = 0; i < n-1; i++) base += Math.abs(nums[i]- nums[i+1]);
int res = base, mx = 0, mn = Integer.MAX_VALUE;
for (int i = 1; i < n-1; i++) {
mx = Math.max(mx, Math.min(nums[i], nums[i+1]));
mn = Math.min(mn, Math.max(nums[i], nums[i+1]));
}
if (mx < mn) res = Math.max(res, base + 2*(mn - mx));
for (int i = 1; i < n-1; i++) {
res = Math.max(res, base + Math.abs(nums[0]- nums[i+1]) - Math.abs(nums[i]- nums[i+1]));
res = Math.max(res, base + Math.abs(nums[n-1]- nums[i-1]) - Math.abs(nums[i]- nums[i-1]));
}
return res;
}
}
classSolution {
funmaxValueAfterReverse(nums: IntArray): Int {
val n = nums.size
var base = 0for (i in0 until n-1) base += kotlin.math.abs(nums[i] - nums[i+1])
var res = base
var mx = 0var mn = Int.MAX_VALUE
for (i in1 until n-1) {
mx = maxOf(mx, minOf(nums[i], nums[i+1]))
mn = minOf(mn, maxOf(nums[i], nums[i+1]))
}
if (mx < mn) res = maxOf(res, base + 2*(mn - mx))
for (i in1 until n-1) {
res = maxOf(res, base + kotlin.math.abs(nums[0] - nums[i+1]) - kotlin.math.abs(nums[i] - nums[i+1]))
res = maxOf(res, base + kotlin.math.abs(nums[n-1] - nums[i-1]) - kotlin.math.abs(nums[i] - nums[i-1]))
}
return res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
defmaxValueAfterReverse(self, nums: list[int]) -> int:
n = len(nums)
base = sum(abs(nums[i] - nums[i+1]) for i in range(n-1))
res = base
mx, mn =0, float('inf')
for i in range(1, n-1):
mx = max(mx, min(nums[i], nums[i+1]))
mn = min(mn, max(nums[i], nums[i+1]))
if mx < mn:
res = max(res, base +2*(mn - mx))
for i in range(1, n-1):
res = max(res, base + abs(nums[0] - nums[i+1]) - abs(nums[i] - nums[i+1]))
res = max(res, base + abs(nums[n-1] - nums[i-1]) - abs(nums[i] - nums[i-1]))
return res