Skip to content

Commit e4f7e15

Browse files
authoredJul 20, 2023
feat: add solutions to lc problem: No.1499 (doocs#1250)
No.1499.Max Value of Equation
1 parent bf95cb0 commit e4f7e15

File tree

7 files changed

+565
-96
lines changed

7 files changed

+565
-96
lines changed
 

‎solution/1400-1499/1499.Max Value of Equation/README.md

+259-24
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,38 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47-
**方法一:单调队列**
47+
**方法一:优先队列(大根堆)**
4848

49-
区间(窗口)最值问题,使用单调队列优化。q 按 `y - x` 单调递减。
49+
题目要求 $y_i + y_j + |x_i - x_j|$ 的最大值,其中 $i \lt j$,并且 $|x_i - x_j| \leq k$。由于 $x_i$ 是严格单调递增的,那么:
5050

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$ 的长度。
5279

5380
<!-- tabs:start -->
5481

@@ -59,16 +86,30 @@
5986
```python
6087
class Solution:
6188
def findMaxValueOfEquation(self, points: List[List[int]], k: int) -> int:
62-
q = deque([points[0]])
6389
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:
65106
while q and x - q[0][0] > k:
66107
q.popleft()
67108
if q:
68109
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]:
70111
q.pop()
71-
q.append([x, y])
112+
q.append((x, y))
72113
return ans
73114
```
74115

@@ -79,20 +120,40 @@ class Solution:
79120
```java
80121
class Solution {
81122
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);
82144
Deque<int[]> q = new ArrayDeque<>();
83-
int ans = Integer.MIN_VALUE;
84-
for (int[] p : points) {
145+
for (var p : points) {
85146
int x = p[0], y = p[1];
86147
while (!q.isEmpty() && x - q.peekFirst()[0] > k) {
87-
q.poll();
148+
q.pollFirst();
88149
}
89150
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]);
91152
}
92-
while (!q.isEmpty() && y - x > q.peekLast()[1] - q.peekLast()[0]) {
153+
while (!q.isEmpty() && y - x >= q.peekLast()[1] - q.peekLast()[0]) {
93154
q.pollLast();
94155
}
95-
q.offer(p);
156+
q.offerLast(p);
96157
}
97158
return ans;
98159
}
@@ -105,14 +166,41 @@ class Solution {
105166
class Solution {
106167
public:
107168
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;
110171
for (auto& p : points) {
111172
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);
116204
}
117205
return ans;
118206
}
@@ -123,20 +211,58 @@ public:
123211

124212
```go
125213
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{}
128254
for _, p := range points {
129255
x, y := p[0], p[1]
130256
for len(q) > 0 && x-q[0][0] > k {
131257
q = q[1:]
132258
}
133259
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])
135261
}
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] {
137263
q = q[:len(q)-1]
138264
}
139-
q = append(q, p)
265+
q = append(q, [2]int{x, y})
140266
}
141267
return ans
142268
}
@@ -149,6 +275,115 @@ func max(a, b int) int {
149275
}
150276
```
151277

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+
152387
### **...**
153388

154389
```

0 commit comments

Comments
 (0)