【LeetCode 算法】Max Value of Equation 满足不等式的最大值-优先队列

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+xixj 的 最大值,其中 ∣ 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 xixj<=k1<=i<j<=points.length

题目测试数据保证至少存在一对能够满足 ∣ x i − x j ∣ < = k |x_i - x_j| <= k xixj<=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==2108<=points[i][0],points[i][1]<=1080<=k<=2108对于所有的1<=i<j<=points.lengthpoints[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+xixj的最大值,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+xixjf=yi+yj+xjxi
为了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+(yixi),所以最符合条件的 i i i 应该是 y i − x i y_i-x_i yixi 最大。

而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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eric.Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值