Medium
题目描述
给你两个长度相等的整数数组,返回下面表达式的最大值:
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
其中最大值是在满足 0 <= i, j < arr1.length 的所有 i 和 j 上取得的。
示例 1:
输入:arr1 = [1,2,3,4], arr2 = [-1,4,5,6]
输出:13
示例 2:
输入:arr1 = [1,-2,-5,0,10], arr2 = [0,-2,-1,-7,-4]
输出:20
约束条件:
- 2 <= arr1.length == arr2.length <= 40000
- -10^6 <= arr1[i], arr2[i] <= 10^6
提示:
- 使用 abs(A) + abs(B) = max(A+B, A-B, -A+B, -A-B) 的思想。
解题思路
这道题的关键在于利用绝对值的性质来化简表达式。对于 |arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|,我们需要巧妙地处理绝对值。
根据提示,对于任意两个数 A 和 B,有:|A| + |B| = max(A+B, A-B, -A+B, -A-B)
设 A = arr1[i] - arr1[j],B = arr2[i] - arr2[j],C = i - j
那么原表达式变为:|A| + |B| + |C|
由于 i 和 j 的大小关系确定了 C 的符号,我们可以分情况讨论:
- 当 i > j 时,C = i - j > 0
- 当 i < j 时,C = i - j < 0
对于每种情况,我们应用绝对值公式:|A| + |B| = max(A+B, A-B, -A+B, -A-B)
这样原问题转化为求四个表达式的最大值:
- (arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j)
- (arr1[i] - arr2[i] + i) - (arr1[j] - arr2[j] + j)
- (-arr1[i] + arr2[i] + i) - (-arr1[j] + arr2[j] + j)
- (-arr1[i] - arr2[i] + i) - (-arr1[j] - arr2[j] + j)
对于每个表达式,我们只需要找到对应组合的最大值和最小值,它们的差就是该表达式的最大值。
代码实现
class Solution {
public:
int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
int n = arr1.size();
// 四种组合的最大值和最小值
int max1 = INT_MIN, min1 = INT_MAX; // arr1[i] + arr2[i] + i
int max2 = INT_MIN, min2 = INT_MAX; // arr1[i] - arr2[i] + i
int max3 = INT_MIN, min3 = INT_MAX; // -arr1[i] + arr2[i] + i
int max4 = INT_MIN, min4 = INT_MAX; // -arr1[i] - arr2[i] + i
for (int i = 0; i < n; i++) {
int val1 = arr1[i] + arr2[i] + i;
int val2 = arr1[i] - arr2[i] + i;
int val3 = -arr1[i] + arr2[i] + i;
int val4 = -arr1[i] - arr2[i] + i;
max1 = max(max1, val1); min1 = min(min1, val1);
max2 = max(max2, val2); min2 = min(min2, val2);
max3 = max(max3, val3); min3 = min(min3, val3);
max4 = max(max4, val4); min4 = min(min4, val4);
}
return max({max1 - min1, max2 - min2, max3 - min3, max4 - min4});
}
};
class Solution:
def maxAbsValExpr(self, arr1: List[int], arr2: List[int]) -> int:
n = len(arr1)
# 四种组合的最大值和最小值
max1 = min1 = arr1[0] + arr2[0] + 0
max2 = min2 = arr1[0] - arr2[0] + 0
max3 = min3 = -arr1[0] + arr2[0] + 0
max4 = min4 = -arr1[0] - arr2[0] + 0
for i in range(n):
val1 = arr1[i] + arr2[i] + i
val2 = arr1[i] - arr2[i] + i
val3 = -arr1[i] + arr2[i] + i
val4 = -arr1[i] - arr2[i] + i
max1 = max(max1, val1)
min1 = min(min1, val1)
max2 = max(max2, val2)
min2 = min(min2, val2)
max3 = max(max3, val3)
min3 = min(min3, val3)
max4 = max(max4, val4)
min4 = min(min4, val4)
return max(max1 - min1, max2 - min2, max3 - min3, max4 - min4)
public class Solution {
public int MaxAbsValExpr(int[] arr1, int[] arr2) {
int n = arr1.Length;
// 四种组合的最大值和最小值
int max1 = int.MinValue, min1 = int.MaxValue;
int max2 = int.MinValue, min2 = int.MaxValue;
int max3 = int.MinValue, min3 = int.MaxValue;
int max4 = int.MinValue, min4 = int.MaxValue;
for (int i = 0; i < n; i++) {
int val1 = arr1[i] + arr2[i] + i;
int val2 = arr1[i] - arr2[i] + i;
int val3 = -arr1[i] + arr2[i] + i;
int val4 = -arr1[i] - arr2[i] + i;
max1 = Math.Max(max1, val1);
min1 = Math.Min(min1, val1);
max2 = Math.Max(max2, val2);
min2 = Math.Min(min2, val2);
max3 = Math.Max(max3, val3);
min3 = Math.Min(min3, val3);
max4 = Math.Max(max4, val4);
min4 = Math.Min(min4, val4);
}
return Math.Max(Math.Max(max1 - min1, max2 - min2),
Math.Max(max3 - min3, max4 - min4));
}
}
var maxAbsValExpr = function(arr1, arr2) {
const n = arr1.length;
// 四种组合的最大值和最小值
let max1 = -Infinity, min1 = Infinity;
let max2 = -Infinity, min2 = Infinity;
let max3 = -Infinity, min3 = Infinity;
let max4 = -Infinity, min4 = Infinity;
for (let i = 0; i < n; i++) {
const val1 = arr1[i] + arr2[i] + i;
const val2 = arr1[i] - arr2[i] + i;
const val3 = -arr1[i] + arr2[i] + i;
const val4 = -arr1[i] - arr2[i] + i;
max1 = Math.max(max1, val1);
min1 = Math.min(min1, val1);
max2 = Math.max(max2, val2);
min2 = Math.min(min2, val2);
max3 = Math.max(max3, val3);
min3 = Math.min(min3, val3);
max4 = Math.max(max4, val4);
min4 = Math.min(min4, val4);
}
return Math.max(max1 - min1, max2 - min2, max3 - min3, max4 - min4);
};
复杂度分析
| 复杂度 | 数值 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) |