题目

题目来源:力扣(LeetCode)

给你一个数组 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 。

思路分析

思路一:转换成求区间最大值问题

问题要求解 y(i) + y(j) + |x(i) - x(j)| 的最大值。

由于给定的 points 数组横坐标 x 是从小到大排列的。所以,如果我们保证我们搜索的两个点,points[i] 在 points[j] 的前面,就一定有 x(i) - x(j) < 0。

所以,|x(i) - x(j)| = x(j) - x(i)。

所以,y(i) + y(j) + |x(i) - x(j)| = y(i) + y(j) + x(j) - x(i) = (y(i) - x(i)) + (y(j) + x(j)).

问题就变成了,找到两个点,点 points[i] 的 y(i) - x(i) 和点 points[j] 的 y(j) + x(j) 的和最大。

限制条件是,x(i) <= x(j) 且最大相差 k。

因此,我们可以扫描所有的点,对于每一个点,看前面的点中,只要横坐标相差没有超过 k,其中最大的 y(i) - x(i) 是多少。

我们把问题转换成为了一个求区间最大值的问题。

可以使用一个单调队列来获得区间最大值,队列中存储坐标点, 保持队列单调递减,保证队列头部就是队列中最大的 yi-xi 。

具体地:

  • 定义结果值ans和一个队列que,遍历points
  • 如果当前的x坐标与队首元素相比,如果大于k的话将队首元素出队
  • 然后和处理过的队列的队首元素用公式求值,和ans取较大值再赋值给ans
  • 然后和队尾元素比较yi-xi的值,如果大于队尾元素,则队尾元素出队
  • 最后当前元素进队列

代码:

  1. /**
  2. * @param {number[][]} points
  3. * @param {number} k
  4. * @return {number}
  5. */
  6. var findMaxValueOfEquation = function (points, k) {
  7. let len = points.length,
  8. max = -Infinity,
  9. queue = [];
  10. for (let j = 0; j < len; j++) {
  11. let [xj, yj] = points[j];
  12. // 把队列头部不满足条件 |xi - xj| <= k 的元素 shift 掉
  13. while (queue.length > 0 && xj - queue[0][0] > k) queue.shift();
  14. // 更新最大值
  15. if (queue.length > 0) {
  16. max = Math.max(queue[0][1] - queue[0][0] + xj + yj, max);
  17. }
  18. // 在把当前的 points[j] push 加入到队尾之前,把队列尾部比 points[j] 的 yj-xj
  19. // 小的元素 pop 掉,保证队列单调递减
  20. while (queue.length > 0 && (queue[queue.length - 1][1] - queue[queue.length - 1][0]) < (yj - xj)) queue.pop();
  21. queue.push(points[j]);
  22. }
  23. return max;
  24. };

https://leetcode-cn.com/problems/max-value-of-equation/solution/1499-hua-dong-chuang-kou-dan-diao-di-jia-2xv0/