1、重要的数学推导:
|a| = Max(a, -a)
|a-b|+|c-d|
= Max(a-b, b-a) + Max(c-d, d-c) // max(a-b, -(a-b)) + max(c-d, -(c-d))
= Max{
(a-b)+(c-d),
(b-a)+(c-d), // -(a - b) + (c - d)
(a-b)+(d-c),
(b-a)+(d-c), // -(a - b) + (c - d)
}
2、对于此题就有:
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
= max(arr1[i] - arr1[j], arr1[j] - arr1[i]) + max(arr2[i] - arr2[j], arr2[j]-arr2[j]) + max(i-j, j-i)
=max{
(arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j) //式1
(arr1[i] + arr2[i] - i) - (arr1[j] + arr2[j] - j) //式2
(arr1[i] - arr2[i] + i) - (arr1[j] - arr2[j] + j) //式3
(arr1[i] - arr2[i] - i) - (arr1[j] - arr2[j] - j) //式4
-(arr1[i] + arr2[i] + i) + (arr1[j] + arr2[j] + j)//式5
-(arr1[i] + arr2[i] - i) + (arr1[j] + arr2[j] - j)//式6
-(arr1[i] - arr2[i] + i) + (arr1[j] - arr2[j] + j)//式7
-(arr1[i] - arr2[i] - i) + (arr1[j] - arr2[j] - j)//式8
}
设:
A = arr1[i] + arr2[i] + i
B = arr1[i] + arr2[i] - i
C = arr1[i] - arr2[i] + i
D = arr1[i] - arr2[i] - i
因为我们要求绝对值表达式的最大值,所以对于上面的表达式,每个表达式都应取最大值,就是说只有让前面符号是正的最大,前面符号是负的最小才行,这样就能O(n)
算出绝对值表达式的最大值了
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
=max(
max(A) - min(A),
max(B) - min(B),
max(C) - min(C),
max(D) - min(D),
-min(A) + max(A),
-min(B) + max(B),
-min(C) + max(C),
-min(C) + max(C)
)
实现代码:
class Solution {
public:
int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
int f[8][3] = { { 1, 1, 1}, { 1, -1, 1}, { 1,-1,-1}, {1,1,-1},
{-1, 1, 1}, {-1, -1, 1}, {-1, 1,-1}, {-1,-1,-1}};
int ans = INT_MIN;
for(int k = 0; k < 8; k++)
{
int mx = INT_MIN;
int mi = INT_MAX;
for(int i = 0; i < arr1.size(); i++)
{
mx = max(mx, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
mi = min(mi, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
}
ans = max(ans, mx - mi);
}
return ans;
}
};
当然上面其实是有重复的。如: max(A) - min(A) == -min(A) + max(A)
所以可以改成这样:
class Solution {
public:
int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
int f[4][3] = { { 1, 1, 1}, { 1, -1, 1}, { 1,-1,-1}, {1,1,-1}};
int ans = INT_MIN;
for(int k = 0; k < 4; k++)
{
int mx = INT_MIN;
int mi = INT_MAX;
for(int i = 0; i < arr1.size(); i++)
{
mx = max(mx, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
mi = min(mi, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
}
ans = max(ans, mx - mi);
}
return ans;
}
};