给你两个长度相等的整数数组,返回下面表达式的最大值:
∣
a
r
r
1
[
i
]
−
a
r
r
1
[
j
]
∣
+
∣
a
r
r
2
[
i
]
−
a
r
r
2
[
j
]
∣
+
∣
i
−
j
∣
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
∣arr1[i]−arr1[j]∣+∣arr2[i]−arr2[j]∣+∣i−j∣
其中下标 i,j 满足 0 <= i, j < arr1.length。
输入:arr1 = [1,2,3,4], arr2 = [-1,4,5,6]
输出:13
输入:arr1 = [1,-2,-5,0,10], arr2 = [0,-2,-1,-7,-4]
输出:20
分析:
这道题目看起来很简单但是 leetcode 上时间复杂度不优化使用暴力法是无法通过的
方法一:暴力法
class Solution {
public:
int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
int res=INT_MIN;
for(int i=0;i<arr1.size();i++)
{
for(int j=i+1;j<arr1.size();j++)
{
res=max(res,abs(arr1[i]-arr1[j])+abs(arr2[i] - arr2[j])+abs(i-j));
}
}
return res;
}
};
这个时间复杂度不够好,所以不能够通过
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
方法二:将问题变成一个数组的问题
- 若 arr1[i]与arr2[i],arr1[j]与arr2[j] 的值都是同时大于0,或者同时小于0。就可以将两个数组的值相加变成一个数组 a[i][0]=arr1[i]+arr2[i]。在将数组通过按照值大小排序。然后用双指针的办法。
- 若arr1[i]与arr2[i],arr1[j]与arr2[j]是一个小于0,一个大于0,那么这个时候我们就要用差来形成以数组c[i][0]=arr1[i]-arr2[i]。用双指针的办法。
例子:
同 index 值符号相同的情况
arr1=[1,-1,4,-5],arr2=[3,-2,1,-1]
a=[[4,0],[-3,1],[5,2],[-6,3]]
排序后a=[[-6,3],[-3,1],[4,0],[5,2]]
会发现这种情况对a操作和对arr1和arr2操作能得到相同的答案
同 index 值符号不同的情况
arr1=[1,-1,4,-5],arr2=[-3,2,-1,1]
a=[[4,0],[-3,1],[5,2],[-6,3]]
排序后a=[[-6,3],[-3,1],[4,0],[5,2]]
会发现这种情况对c操作和对arr1和arr2操作能得到相同的答案
那么同一个数组同时存在两种情况,说明我们需要包含所有情况,所以既要对a进行遍历,也要对c进行遍历
class Solution {
public:
static bool cmp(vector<int> &a,vector<int>&b)//按值大小排序
{
return a[0]<b[0];
}
int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
int res=INT_MIN;
vector<vector<int>> a(arr1.size(),vector<int>(2));//和创建数组
vector<vector<int>> c(arr1.size(),vector<int>(2));//差创建数组
for(int i=0;i<arr1.size();i++)
{
a[i][0]=arr1[i]+arr2[i];
a[i][1]=i;
}
for(int i=0;i<arr1.size();i++)
{
c[i][0]=arr1[i]-arr2[i];
c[i][1]=i;
}
sort(a.begin(),a.end(),cmp);
sort(c.begin(),c.end(),cmp);
int i=0;
int j=a.size()-1;
//两种情况都遍历就包含所有情况
while(i<j)
{
res=max(res,abs(a[i][0]-a[j][0])+abs(a[i][1]-a[j][1]));
if(abs(a[i][1]-a[j-1][1])>abs(a[i][1]-a[j][1]))
j--;
else i++;
}
i=0;
j=a.size()-1;
while(i<j)
{
res=max(res,abs(c[i][0]-c[j][0])+abs(c[i][1]-c[j][1]));
if(abs(c[i][1]-c[j-1][1])>abs(c[i][1]-c[j][1]))
j--;
else i++;
}
return res;
}
};
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)