给你一个数组 points
和一个整数 k
。数组中每个元素都表示二维平面上的点的坐标,并按照横坐标 x 的值从小到大排序。也就是说 points[i] = [xi, yi]
,并且在 1 <= i < j <= points.length
的前提下, xi < xj
总成立。
请你找出 yi + yj + |xi - xj|
的 最大值,其中 |xi - xj| <= k
且 1 <= i < j <= points.length
。
题目测试数据保证至少存在一对能够满足 |xi - xj| <= k
的点。
示例 1:
输入:points = [[1,3],[2,0],[5,10],[6,-10]], k = 1 输出:4 解释:前两个点满足 |xi - xj| <= 1 ,代入方程计算,则得到值 3 + 0 + |1 - 2| = 4 。第三个和第四个点也满足条件,得到值 10 + -10 + |5 - 6| = 1 。 没有其他满足条件的点,所以返回 4 和 1 中最大的那个。
示例 2:
输入:points = [[0,0],[3,0],[9,2]], k = 3 输出:3 解释:只有前两个点满足 |xi - xj| <= 3 ,代入方程后得到值 0 + 0 + |0 - 3| = 3 。
提示:
2 <= points.length <= 10^5
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]
都成立。也就是说,xi
是严格递增的。
提示 1
Use a priority queue to store for each point i, the tuple [yi-xi, xi]
提示 2
Loop through the array and pop elements from the heap if the condition xj - xi > k, where j is the current index and i is the point on top the queue.
提示 3
After popping elements from the queue. If the queue is not empty, calculate the equation with the current point and the point on top of the queue and maximize the answer.
解法1:单调队列
使用一个双端队列 queue,元素为 [x, y−x]。每次遍历一个点时,首先同样要弹出队列头部不满足 xj − xi ≤ k 的元素,然后用队列头部元素和当前元素计算 (yi−xi)+(xj+yj)。。在当前元素进入队列尾端时,需要弹出队列末端小于等于当前 yj−xj 的元素,这样以来,可以使得双端队列保持递减,从而头部元素最大。然后将当前元素压入队列末端。遍历完后,即得到了式子的最大值。
Java版:
class Solution {
public int findMaxValueOfEquation(int[][] points, int k) {
int ans = Integer.MIN_VALUE;
Deque<int[]> queue = new ArrayDeque<>();
for (int[] point : points) {
while (!queue.isEmpty() && point[0] - queue.peek()[0] > k) {
queue.poll();
}
// i < j
// yi + yj + |xi - xj| == yi + yj + xj - xi == yi - xi + yj + xj
if (!queue.isEmpty()) {
ans = Math.max(ans, queue.peek()[1] + point[1] + point[0]);
}
while (!queue.isEmpty() && queue.peekLast()[1] <= point[1] - point[0]) {
queue.pollLast();
}
queue.offer(new int[]{point[0], point[1] - point[0]});
}
return ans;
}
}
Python3版:
class Solution:
def findMaxValueOfEquation(self, points: List[List[int]], k: int) -> int:
queue = deque()
ans = -inf
for x, y in points:
while queue and x - queue[0][0] > k:
queue.popleft()
# yi - xi + yj + xj
if queue:
ans = max(ans, queue[0][1] + y + x)
while queue and queue[-1][1] <= y - x:
queue.pop()
queue.append([x, y - x])
return ans
复杂度分析
-
时间复杂度:O(n),其中 n 是 points 的长度,每个元素最多进入并离开 queue 一次。
-
空间复杂度:O(n),是 queue 的空间复杂度。