44
44
45
45
<!-- 这里可写通用的实现逻辑 -->
46
46
47
- ** 方法一:单调队列 **
47
+ ** 方法一:优先队列(大根堆) **
48
48
49
- 区间(窗口)最值问题,使用单调队列优化。q 按 ` y - x ` 单调递减。
49
+ 题目要求 $y_i + y_j + |x_i - x_j|$ 的最大值,其中 $i \lt j$,并且 $|x_i - x_j| \leq k$。由于 $x_i$ 是严格单调递增的,那么:
50
50
51
- 时间复杂度 $O(n)$。
51
+ $$
52
+ \begin{aligned}
53
+ y_i + y_j + |x_i - x_j| & = y_i + y_j + x_j - x_i \\
54
+ & = (y_i - x_i) + (x_j + y_j)
55
+ \end{aligned}
56
+ $$
57
+
58
+ 因此,对于当前遍历到的点 $(x_j, y_j)$,我们只需要找到前面所有满足 $x_j - x_i \leq k$ 的点 $(x_i, y_i)$ 中 $y_i - x_i$ 的最大值,再加上当前的 $x_j + y_j$ 即可。而 $y_i - x_i$ 的最大值,我们可以使用优先队列(大根堆)来维护。
59
+
60
+ 具体地,我们定义一个优先队列(大根堆) $pq$,堆中每个元素是一个二元组 $(y_i - x_i, x_i)$。
61
+
62
+ 当我们遍历到点 $(x, y)$ 时,如果堆 $pq$ 不为空,并且 $x - pq[ 0] [ 1 ] \gt k$,那么循环将堆顶元素弹出,直到堆为空或者满足 $x - pq[ 0] [ 1 ] \leq k$。此时,堆顶元素 $(y_i - x_i, x_i)$ 即为所有满足 $x_j - x_i \leq k$ 的点中 $y_i - x_i$ 的最大值,此时更新答案 $ans = \max(ans, x + y + pq[ 0] [ 0 ] )$。
63
+
64
+ 然后,我们将点 $(x, y)$ 加入堆中,继续遍历下一个点,直到遍历完整个数组 $points$。
65
+
66
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $points$ 的长度。
67
+
68
+ ** 方法二:单调队列**
69
+
70
+ 这道题实际上需要我们维护的是一个长度为 $k$ 的窗口中 $y-x$ 的最大值,单调队列可以很好地解决这个问题。
71
+
72
+ 具体地,我们定义一个单调队列 $q$,队列中每个元素是一个二元组 $(x_i, y_i)$。
73
+
74
+ 当我们遍历到点 $(x, y)$ 时,如果队列 $q$ 不为空,并且 $x - q[ 0] [ 0 ] \gt k$,那么不断弹出队首元素,直到队列为空或者满足 $x - q[ 0] [ 0 ] \leq k$。此时,队首元素 $(x_i, y_i)$ 即为所有满足 $x_j - x_i \leq k$ 的点中 $y_i - x_i$ 的最大值,此时更新答案 $ans = \max(ans, x + y + y_i - x_i)$。
75
+
76
+ 接下来,在将点 $(x, y)$ 加入队尾之前,我们将队列中所有 $y_i - x_i \leq y - x$ 的元素 $(x_i, y_i)$ 弹出队列,然后将点 $(x, y)$ 加入队尾。继续遍历下一个点,直到遍历完整个数组 $points$。
77
+
78
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $points$ 的长度。
52
79
53
80
<!-- tabs:start -->
54
81
59
86
``` python
60
87
class Solution :
61
88
def findMaxValueOfEquation (self , points : List[List[int ]], k : int ) -> int :
62
- q = deque([points[0 ]])
63
89
ans = - inf
64
- for x, y in points[1 :]:
90
+ pq = []
91
+ for x, y in points:
92
+ while pq and x - pq[0 ][1 ] > k:
93
+ heappop(pq)
94
+ if pq:
95
+ ans = max (ans, x + y - pq[0 ][0 ])
96
+ heappush(pq, (x - y, x))
97
+ return ans
98
+ ```
99
+
100
+ ``` python
101
+ class Solution :
102
+ def findMaxValueOfEquation (self , points : List[List[int ]], k : int ) -> int :
103
+ ans = - inf
104
+ q = deque()
105
+ for x, y in points:
65
106
while q and x - q[0 ][0 ] > k:
66
107
q.popleft()
67
108
if q:
68
109
ans = max (ans, x + y + q[0 ][1 ] - q[0 ][0 ])
69
- while q and y - x > q[- 1 ][1 ] - q[- 1 ][0 ]:
110
+ while q and y - x >= q[- 1 ][1 ] - q[- 1 ][0 ]:
70
111
q.pop()
71
- q.append([ x, y] )
112
+ q.append(( x, y) )
72
113
return ans
73
114
```
74
115
@@ -79,20 +120,40 @@ class Solution:
79
120
``` java
80
121
class Solution {
81
122
public int findMaxValueOfEquation (int [][] points , int k ) {
123
+ int ans = - (1 << 30 );
124
+ Priority<int[]> pq = new Priority<> ((a, b) - > b[0 ] - a[0 ]);
125
+ for (var p : points) {
126
+ int x = p[0 ], y = p[1 ];
127
+ while (! hp. isEmpty() && x - hp. peek()[1 ] > k) {
128
+ hp. poll();
129
+ }
130
+ if (! hp. isEmpty()) {
131
+ ans = Math . max(ans, x + y + hp. peek()[0 ]);
132
+ }
133
+ hp. offer(new int [] {y - x, x});
134
+ }
135
+ return ans;
136
+ }
137
+ }
138
+ ```
139
+
140
+ ``` java
141
+ class Solution {
142
+ public int findMaxValueOfEquation (int [][] points , int k ) {
143
+ int ans = - (1 << 30 );
82
144
Deque<int[]> q = new ArrayDeque<> ();
83
- int ans = Integer . MIN_VALUE ;
84
- for (int [] p : points) {
145
+ for (var p : points) {
85
146
int x = p[0 ], y = p[1 ];
86
147
while (! q. isEmpty() && x - q. peekFirst()[0 ] > k) {
87
- q. poll ();
148
+ q. pollFirst ();
88
149
}
89
150
if (! q. isEmpty()) {
90
- ans = Math . max(ans, y + x + q. peekFirst()[1 ] - q. peekFirst()[0 ]);
151
+ ans = Math . max(ans, x + y + q. peekFirst()[1 ] - q. peekFirst()[0 ]);
91
152
}
92
- while (! q. isEmpty() && y - x > q. peekLast()[1 ] - q. peekLast()[0 ]) {
153
+ while (! q. isEmpty() && y - x >= q. peekLast()[1 ] - q. peekLast()[0 ]) {
93
154
q. pollLast();
94
155
}
95
- q. offer (p);
156
+ q. offerLast (p);
96
157
}
97
158
return ans;
98
159
}
@@ -105,14 +166,41 @@ class Solution {
105
166
class Solution {
106
167
public:
107
168
int findMaxValueOfEquation(vector<vector<int >>& points, int k) {
108
- deque<vector< int >> q ;
109
- int ans = INT_MIN ;
169
+ int ans = -(1 << 30) ;
170
+ priority_queue<pair< int, int>> pq ;
110
171
for (auto& p : points) {
111
172
int x = p[ 0] , y = p[ 1] ;
112
- while (!q.empty() && x - q.front()[ 0] > k) q.pop_front();
113
- if (!q.empty()) ans = max(ans, y + x + q.front()[ 1] - q.front()[ 0] );
114
- while (!q.empty() && y - x > q.back()[ 1] - q.back()[ 0] ) q.pop_back();
115
- q.push_back(p);
173
+ while (pq.size() && x - pq.top().second > k) {
174
+ pq.pop();
175
+ }
176
+ if (pq.size()) {
177
+ ans = max(ans, x + y + pq.top().first);
178
+ }
179
+ pq.emplace(y - x, x);
180
+ }
181
+ return ans;
182
+ }
183
+ };
184
+ ```
185
+
186
+ ```cpp
187
+ class Solution {
188
+ public:
189
+ int findMaxValueOfEquation(vector<vector<int>>& points, int k) {
190
+ int ans = -(1 << 30);
191
+ deque<pair<int, int>> q;
192
+ for (auto& p : points) {
193
+ int x = p[0], y = p[1];
194
+ while (!q.empty() && x - q.front().first > k) {
195
+ q.pop_front();
196
+ }
197
+ if (!q.empty()) {
198
+ ans = max(ans, x + y + q.front().second - q.front().first);
199
+ }
200
+ while (!q.empty() && y - x >= q.back().second - q.back().first) {
201
+ q.pop_back();
202
+ }
203
+ q.emplace_back(x, y);
116
204
}
117
205
return ans;
118
206
}
@@ -123,20 +211,58 @@ public:
123
211
124
212
``` go
125
213
func findMaxValueOfEquation (points [][]int , k int ) int {
126
- q := [][]int{}
127
- ans := math.MinInt32
214
+ ans := -(1 << 30 )
215
+ hp := hp{}
216
+ for _ , p := range points {
217
+ x , y := p[0 ], p[1 ]
218
+ for hp.Len () > 0 && x-hp[0 ].x > k {
219
+ heap.Pop (&hp)
220
+ }
221
+ if hp.Len () > 0 {
222
+ ans = max (ans, x+y+hp[0 ].v )
223
+ }
224
+ heap.Push (&hp, pair{y - x, x})
225
+ }
226
+ return ans
227
+ }
228
+
229
+ func max (a , b int ) int {
230
+ if a > b {
231
+ return a
232
+ }
233
+ return b
234
+ }
235
+
236
+ type pair struct { v, x int }
237
+
238
+ type hp []pair
239
+
240
+ func (h hp ) Len () int { return len (h) }
241
+ func (h hp ) Less (i , j int ) bool {
242
+ a , b := h[i], h[j]
243
+ return a.v > b.v
244
+ }
245
+ func (h hp ) Swap (i , j int ) { h[i], h[j] = h[j], h[i] }
246
+ func (h *hp ) Push (v interface {}) { *h = append (*h, v.(pair)) }
247
+ func (h *hp ) Pop () interface {} { a := *h; v := a[len (a)-1 ]; *h = a[:len (a)-1 ]; return v }
248
+ ```
249
+
250
+ ``` go
251
+ func findMaxValueOfEquation (points [][]int , k int ) int {
252
+ ans := -(1 << 30 )
253
+ q := [][2 ]int {}
128
254
for _ , p := range points {
129
255
x , y := p[0 ], p[1 ]
130
256
for len (q) > 0 && x-q[0 ][0 ] > k {
131
257
q = q[1 :]
132
258
}
133
259
if len (q) > 0 {
134
- ans = max(ans, y+x +q[0][1]-q[0][0])
260
+ ans = max (ans, x+y +q[0 ][1 ]-q[0 ][0 ])
135
261
}
136
- for len(q) > 0 && y-x > q[len(q)-1][1]-q[len(q)-1][0] {
262
+ for len (q) > 0 && y-x >= q[len (q)-1 ][1 ]-q[len (q)-1 ][0 ] {
137
263
q = q[:len (q)-1 ]
138
264
}
139
- q = append(q, p )
265
+ q = append (q, [ 2 ] int {x, y} )
140
266
}
141
267
return ans
142
268
}
@@ -149,6 +275,115 @@ func max(a, b int) int {
149
275
}
150
276
```
151
277
278
+ ### ** TypeScript**
279
+
280
+ ``` ts
281
+ function findMaxValueOfEquation(points : number [][], k : number ): number {
282
+ let ans = - (1 << 30 );
283
+ const pq = new Heap <[number , number ]>((a , b ) => b [0 ] - a [0 ]);
284
+ for (const [x, y] of points ) {
285
+ while (pq .size () && x - pq .top ()[1 ] > k ) {
286
+ pq .pop ();
287
+ }
288
+ if (pq .size ()) {
289
+ ans = Math .max (ans , x + y + pq .top ()[0 ]);
290
+ }
291
+ pq .push ([y - x , x ]);
292
+ }
293
+ return ans ;
294
+ }
295
+
296
+ type Compare <T > = (lhs : T , rhs : T ) => number ;
297
+
298
+ class Heap <T = number > {
299
+ data: Array <T | null >;
300
+ lt: (i : number , j : number ) => boolean ;
301
+ constructor ();
302
+ constructor (data : T []);
303
+ constructor (compare : Compare <T >);
304
+ constructor (data : T [], compare : Compare <T >);
305
+ constructor (data : T [] | Compare <T >, compare ? : (lhs : T , rhs : T ) => number );
306
+ constructor (
307
+ data : T [] | Compare <T > = [],
308
+ compare : Compare <T > = (lhs : T , rhs : T ) =>
309
+ lhs < rhs ? - 1 : lhs > rhs ? 1 : 0 ,
310
+ ) {
311
+ if (typeof data === ' function' ) {
312
+ compare = data ;
313
+ data = [];
314
+ }
315
+ this .data = [null , ... data ];
316
+ this .lt = (i , j ) => compare (this .data [i ]! , this .data [j ]! ) < 0 ;
317
+ for (let i = this .size (); i > 0 ; i -- ) this .heapify (i );
318
+ }
319
+
320
+ size(): number {
321
+ return this .data .length - 1 ;
322
+ }
323
+
324
+ push(v : T ): void {
325
+ this .data .push (v );
326
+ let i = this .size ();
327
+ while (i >> 1 !== 0 && this .lt (i , i >> 1 )) this .swap (i , (i >>= 1 ));
328
+ }
329
+
330
+ pop(): T {
331
+ this .swap (1 , this .size ());
332
+ const top = this .data .pop ();
333
+ this .heapify (1 );
334
+ return top ! ;
335
+ }
336
+
337
+ top(): T {
338
+ return this .data [1 ]! ;
339
+ }
340
+ heapify(i : number ): void {
341
+ while (true ) {
342
+ let min = i ;
343
+ const [l, r, n] = [i * 2 , i * 2 + 1 , this .data .length ];
344
+ if (l < n && this .lt (l , min )) min = l ;
345
+ if (r < n && this .lt (r , min )) min = r ;
346
+ if (min !== i ) {
347
+ this .swap (i , min );
348
+ i = min ;
349
+ } else break ;
350
+ }
351
+ }
352
+
353
+ clear(): void {
354
+ this .data = [null ];
355
+ }
356
+
357
+ private swap(i : number , j : number ): void {
358
+ const d = this .data ;
359
+ [d [i ], d [j ]] = [d [j ], d [i ]];
360
+ }
361
+ }
362
+ ```
363
+
364
+ ``` ts
365
+ function findMaxValueOfEquation(points : number [][], k : number ): number {
366
+ let ans = - (1 << 30 );
367
+ const q: number [][] = [];
368
+ for (const [x, y] of points ) {
369
+ while (q .length > 0 && x - q [0 ][0 ] > k ) {
370
+ q .shift ();
371
+ }
372
+ if (q .length > 0 ) {
373
+ ans = Math .max (ans , x + y + q [0 ][1 ] - q [0 ][0 ]);
374
+ }
375
+ while (
376
+ q .length > 0 &&
377
+ y - x > q [q .length - 1 ][1 ] - q [q .length - 1 ][0 ]
378
+ ) {
379
+ q .pop ();
380
+ }
381
+ q .push ([x , y ]);
382
+ }
383
+ return ans ;
384
+ }
385
+ ```
386
+
152
387
### ** ...**
153
388
154
389
```
0 commit comments