Max Value of Equation 满足不等式的最大值
问题描述:
给你一个数组 points 和一个整数 k 。数组中每个元素都表示二维平面上的点的坐标,并按照横坐标 x 的值从小到大排序。也就是说 p o i n t s [ i ] = [ x i , y i ] points[i] = [x_i, y_i] points[i]=[xi,yi],并且在 1 < = i < j < = p o i n t s . l e n g t h 1 <= i < j <= points.length 1<=i<j<=points.length 的前提下, x i < x j x_i < x_j xi<xj 总成立。
请你找出 y i + y j + ∣ x i − x j ∣ y_i + y_j + |x_i - x_j| yi+yj+∣xi−xj∣ 的 最大值,其中 ∣ x i − x j ∣ < = k 且 1 < = i < j < = p o i n t s . l e n g t h |x_i - x_j| <= k 且 1 <= i < j <= points.length ∣xi−xj∣<=k且1<=i<j<=points.length。
题目测试数据保证至少存在一对能够满足 ∣ x i − x j ∣ < = k |x_i - x_j| <= k ∣xi−xj∣<=k 的点。
2 < = p o i n t s . l e n g t h < = 1 0 4 p o i n t s [ i ] . l e n g t h = = 2 − 1 0 8 < = p o i n t s [ i ] [ 0 ] , p o i n t s [ i ] [ 1 ] < = 1 0 8 0 < = k < = 2 ∗ 1 0 8 对于所有的 1 < = i < j < = p o i n t s . l e n g t h , p o i n t s [ i ] [ 0 ] < p o i n t s [ j ] [ 0 ] 都成立。也就是说, x i 是严格递增的 2 <= points.length <= 10^4\\ points[i].length == 2\\ -10^8 <= points[i][0], points[i][1] <= 10^8\\ 0 <= k <= 2 * 10^8\\ 对于所有的1 <= i < j <= points.length ,points[i][0] < points[j][0] 都成立。也就是说,x_i 是严格递增的 2<=points.length<=104points[i].length==2−108<=points[i][0],points[i][1]<=1080<=k<=2∗108对于所有的1<=i<j<=points.length,points[i][0]<points[j][0]都成立。也就是说,xi是严格递增的
分析
其实这个问题谜底就在谜面上。
中文是满足不等式,英文是等式的最大值。
points是一堆二维平面坐标的数组,而且是以x非递减的顺序排列。
要求找出 y i + y j + ∣ x i − x j ∣ 的最大值, i < j y_i+y_j+|x_i-x_j|的最大值,i<j yi+yj+∣xi−xj∣的最大值,i<j。
所以
j
j
j一定是在
i
i
i的右侧,而且
p
o
i
n
t
s
points
points是非递减,所以
x
j
>
x
i
x_j>x_i
xj>xi.
f
=
y
i
+
y
j
+
∣
x
i
−
x
j
∣
f
=
y
i
+
y
j
+
x
j
−
x
i
f = y_i+y_j+|x_i-x_j|\\ f = y_i+y_j+x_j-x_i
f=yi+yj+∣xi−xj∣f=yi+yj+xj−xi
为了f最大,当固定j时,
y
j
+
x
j
=
C
y_j+x_j = C
yj+xj=C,
f
=
C
+
(
y
i
−
x
i
)
f = C +(y_i-x_i)
f=C+(yi−xi),所以最符合条件的
i
i
i 应该是
y
i
−
x
i
y_i-x_i
yi−xi 最大。
而k的存在就是对i和j的范围限制。
可以使用优先队列进行处理。 所以整体的时间复杂度大概为 O ( N l o g N ) O(NlogN) O(NlogN)
代码
优先队列
public int findMaxValueOfEquation(int[][] points, int k) {
int n = points.length;
//x,y-x
PriorityQueue<int[]> pq = new PriorityQueue<int[]>((a,b)->{
if(a[1]==b[1]) return a[0]-b[0];
return b[1]-a[1];
});
int ans = Integer.MIN_VALUE;
for(int i =0;i<n;){
int[] p = points[i];
int xj = p[0],yj = p[1];
while(!pq.isEmpty()&& (xj - pq.peek()[0])>k){
pq.poll();
}
// pq maybe null or at least one e.
if(!pq.isEmpty()){
//calc
ans = Math.max(ans, xj+yj+pq.peek()[1]);
}
pq.offer(new int[]{ xj, yj-xj});
i++;
}
return ans;
}
时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN)
空间复杂度 O ( k ) O(k) O(k)
Tag
Array
PriorityQueue