【每日一题Day272】LC1499满足不等式的最大值 | 单调队列 大顶堆

满足不等式的最大值【LC1499】

给你一个数组 points 和一个整数 k 。数组中每个元素都表示二维平面上的点的坐标,并按照横坐标 x 的值从小到大排序。也就是说 points[i] = [xi, yi] ,并且在 1 <= i < j <= points.length 的前提下, xi < xj 总成立。

请你找出 yi + yj + |xi - xj|最大值,其中 |xi - xj| <= k1 <= i < j <= points.length

题目测试数据保证至少存在一对能够满足 |xi - xj| <= k 的点。

新知识++

  • 思路

    • 转化:枚举 j j j,问题变成计算 y i − x i y_i-x_i yixi的最大值,其中要求 i < j i<j i<j并且 x i ≥ x j − k x_i \ge x_j-k xixjk
      y i + y j + ∣ x i − x j ∣ = x j + y j + y i − x i y_i + y_j + |x_i - x_j|=x_j+y_j+y_i-x_i yi+yj+xixj=xj+yj+yixi

    • 实现:大根堆

      使用大根堆记录二元组 [ x i , y i − x i ] [x_i,y_i-x_i] [xi,yixi],堆以 y i − x i y_i-x_i yixi降序排序,然后枚举 j j j

      • 获得最值:如果堆顶元素下标与 j j j差值大于 k k k,那么将堆顶元素弹出;如果有下标差值小于等于 k k k的堆顶元素,那么判断是否需要更新答案。
      • 直接入堆
    • 实现:单调队列

      使用单调队列记录二元组 [ x i , y i − x i ] [x_i,y_i-x_i] [xi,yixi],队列中元素以 y i − x i y_i-x_i yixi降序排列,然后枚举 j j j

      • 如果队首元素下标与 j j j差值大于 k k k,那么将队首元素弹出;如果有下标差值小于等于 k k k的队首元素,那么判断是否需要更新答案
      • 入队时,需要保持递减顺序,如果队尾元素小于 y j − x j y_j-x_j yjxj,那么将队尾元素弹出,然后再进行入队【要求最大值,那么队首元素必须为最大,老员工的能力必须比新来的强】
单调队列
class Solution {
    public int findMaxValueOfEquation(int[][] points, int k) {
        int ans = Integer.MIN_VALUE;
        var q = new ArrayDeque<int[]>();
        for (var p : points) {
            int x = p[0], y = p[1];
            while (!q.isEmpty() && q.peekFirst()[0] < x - k) // 队首超出范围
                q.pollFirst(); // 弹它!
            if (!q.isEmpty())
                ans = Math.max(ans, x + y + q.peekFirst()[1]); // 加上最大的 yi-xi
            while (!q.isEmpty() && q.peekLast()[1] <= y - x) // 队尾不如新来的强
                q.pollLast(); // 弹它!
            q.addLast(new int[]{x, y - x});
        }
        return ans;
    }
}

作者:灵茶山艾府
链接:https://leetcode.cn/problems/max-value-of-equation/solutions/2352457/on-dan-diao-dui-lie-fu-ti-dan-pythonjava-hhrr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 复杂度
    • 时间复杂度: O ( n ) \mathcal{O}(n) O(n)
    • 空间复杂度: O ( n ) \mathcal{O}(n) O(n)
class Solution {
    public int findMaxValueOfEquation(int[][] points, int k) {
        int ans = -(1 << 30);
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[0] - a[0]);
        for (var p : points) {
            int x = p[0], y = p[1];
            while (!pq.isEmpty() && x - pq.peek()[1] > k) {
                pq.poll();
            }
            if (!pq.isEmpty()) {
                ans = Math.max(ans, x + y + pq.peek()[0]);
            }
            pq.offer(new int[] {y - x, x});
        }
        return ans;
    }
}

作者:ylb
链接:https://leetcode.cn/problems/max-value-of-equation/solutions/2352475/python3javacgotypescript-yi-ti-shuang-ji-dtrj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 复杂度
    • 时间复杂度: O ( n log ⁡ n ) \mathcal{O}(n \log n) O(nlogn)
    • 空间复杂度: O ( n ) \mathcal{O}(n) O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值