• 1499. 满足不等式的最大值 堆/双端队列


    1499. 满足不等式的最大值

    给你一个数组 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 是严格递增的。

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/max-value-of-equation
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    做题结果

    成功,堆,后面参考标签单调队列

     方法1:堆

    yi + yj + |xi - xj|,因为xi

    主要特点是采取了懒删除策略,保存前面索引的位置与 yi-xi,按 yi-xi从大到小排序堆

    1. 把堆顶和x距离太远的删掉(懒删除)

    2. 非空情况比较 max(yi+yj+堆顶,ans)

    3. 当前元素 {xi,yi-xi} 加入堆

    1. class Solution {
    2. public int findMaxValueOfEquation(int[][] points, int k) {
    3. PriorityQueue<int[]> pq= new PriorityQueue<>((a,b)->b[1]-a[1]);
    4. int n = points.length;
    5. int ans = Integer.MIN_VALUE;
    6. for(int i = 0; i < n; i++){
    7. int[] point = points[i];
    8. while (!pq.isEmpty()&&point[0]-pq.peek()[0]>k) pq.poll();
    9. if(!pq.isEmpty()) ans = Math.max(ans,point[0]+point[1]+pq.peek()[1]);
    10. pq.offer(new int[]{point[0],point[1]-point[0]});
    11. }
    12. return ans;
    13. }
    14. }

    时间复杂度:O(nlogn)

    空间复杂度:O(n)

    方法2:双端队列(单调队列)

    1. 考虑两个情况:

            - 新的值比旧的值小,新的值可能作为有效值算到答案中吗?可能。前面旧值出队,新的值可能变成最大

            - 新的值比旧的值大,旧的值可能作为有效值到答案中吗?不可能。前面旧值出队,新的值还没出队,所以旧值无效了。

    2. 综上,本题维护一个单调下降即可。最大值在最前,最小值最后。前面的值距离超出就出队,后面的值比新值小的就出队,然后新的值加在队列的末尾。这样就用O(n) 的复杂度维护了和堆一样拿到最大值得效果。

    1. class Solution {
    2. public int findMaxValueOfEquation(int[][] points, int k) {
    3. int n = points.length;
    4. int[] deque = new int[n];
    5. int start = 0;
    6. int end = 0;
    7. int ans = Integer.MIN_VALUE;
    8. for (int i = 0; i < n; i++) {
    9. int[] point = points[i];
    10. while (end!=start && point[0] - points[deque[start]][0] > k) ++start;
    11. if (end!=start) ans = Math.max(ans, point[0] + point[1] + (points[deque[start]][1]-points[deque[start]][0]));
    12. int v = point[1] - point[0];
    13. while (end!=start && points[deque[end-1]][1]-points[deque[end-1]][0] < v)--end;
    14. deque[end++]=i;
    15. }
    16. return ans;
    17. }
    18. }

    时间复杂度:O(n)

    空间复杂度:O(n) 

  • 相关阅读:
    Android dumpsys 常用命令
    数据库备份
    现代卷积神经网络 - 批量规范化
    如何在Django中使用模板
    SQL面试题之行转列问题万能模板(过程详细且清晰)
    adb shell命令查看当前屏幕可见最顶层Activity和Fragment及其调用栈
    基于 DSP+FPGA 的排爆机器人控制系统设计与实现
    HTML学生个人网站作业设计成品 HTML+CSS肖战明星人物介绍网页 web结课作业的源码...
    2020华数杯全国大学生数学建模竞赛B题-基于混合模拟退火算法的三维零件的切割模型与计算(附MATLAB代码)
    SSM框架的师范学院教务信息查询系统的设计与实现源码
  • 原文地址:https://blog.csdn.net/yu_duan_hun/article/details/126255471