LeetCode 1499 - Max Value of Equation

This guide will focus on the optimal monotonic queue solution, which achieves linear time complexity and is necessary to

LeetCode Problem 1499

Difficulty: 🔴 Hard
Topics: Array, Queue, Sliding Window, Heap (Priority Queue), Monotonic Queue

Solution

This guide will focus on the optimal monotonic queue solution, which achieves linear time complexity and is necessary to handle the input size limit of 10^5.

Problem Understanding

We are given a list of 2D points sorted in strictly increasing order by their x-coordinate. Each point is represented as [xi, yi], and we are also given an integer k.

Our goal is to find the maximum possible value of the following equation:

$$yi + yj + |xi - xj|$$

subject to the condition:

$$|xi - xj| \leq k$$

where i < j.

Since the points are sorted by x and xi < xj, the absolute value simplifies naturally:

$$|xi - xj| = xj - xi$$

because xj is always greater than xi.

This transforms the equation into:

$$yi + yj + xj - xi$$

We can rearrange it as:

$$(yi - xi) + (yj + xj)$$

This transformation is the key observation of the problem.

For every point j, we want to find a valid earlier point i such that:

$$xj - xi \leq k$$

and among all such valid points, we want the largest possible value of:

$$yi - xi$$

because (yj + xj) is fixed for the current point j.

The constraints are especially important here:

  • points.length can be as large as 100,000
  • Coordinates can be large, up to 10^8
  • Points are already sorted by x-coordinate

A quadratic solution checking every pair would require up to:

$$O(n^2) = 10^{10}$$

operations in the worst case, which is far too slow.

The problem guarantees that at least one valid pair exists, so we never need to worry about returning an invalid result.

Important edge cases include situations where only adjacent points satisfy the distance condition, negative y values that affect equation scoring, and large windows where many candidate points remain valid. We must also carefully remove expired points whose x-distance exceeds k.

Approaches

Brute Force

The most direct approach is to examine every possible pair (i, j) where i < j.

For each pair, we compute:

$$yi + yj + |xi - xj|$$

and check whether:

$$|xi - xj| \leq k$$

If the pair is valid, we update the maximum answer.

This approach is guaranteed to be correct because it evaluates every possible valid pair. However, since there are O(n²) pairs, it becomes infeasible for n = 100,000.

Optimal Approach, Monotonic Queue

The key mathematical observation is:

$$yi + yj + |xi - xj|$$

becomes:

$$(yi - xi) + (yj + xj)$$

For a fixed point j, the value (yj + xj) is constant.

Therefore, we only need to find the largest:

$$yi - xi$$

among all valid previous points satisfying:

$$xj - xi \leq k$$

This naturally suggests maintaining candidate points in a data structure.

We use a deque (double-ended queue) to maintain candidate points in decreasing order of:

$$yi - xi$$

The deque serves two purposes:

  1. It removes expired points that no longer satisfy the distance constraint.
  2. It keeps only the best candidates for maximizing the equation.

By maintaining monotonic order, the best candidate is always at the front of the deque.

Since each point enters and leaves the deque at most once, the total runtime becomes linear.

Approach Time Complexity Space Complexity Notes
Brute Force O(n²) O(1) Checks every valid pair
Optimal O(n) O(n) Uses a monotonic deque to maintain best candidates

Algorithm Walkthrough

  1. Initialize a deque and a variable best_answer.

The deque will store candidate points as tuples:

(x, y - x)

We maintain the deque in decreasing order of (y - x). 2. Iterate through each point (x, y) in points.

This point acts as the current j. 3. Remove expired points from the front of the deque.

If:

$$x - old_x > k$$

then that point can no longer form a valid pair with the current point or any future point because x-values only increase. 4. Compute the candidate equation value.

If the deque is not empty, the front contains the largest available:

$$yi - xi$$

So we calculate:

$$(x + y) + deque[0]$$

and update the maximum answer. 5. Maintain monotonic order.

Before adding the current point, remove elements from the back while:

$$current(y - x) \geq deque[-1]$$

Such points are never useful again because the current point has an equal or better score and a larger x-value. 6. Insert the current point into the deque.

Store:

(x, y - x) 7. Continue until all points are processed.

Why it works

The deque always maintains valid candidate points sorted in decreasing order of (yi - xi). The front therefore always contains the best possible previous point for maximizing the equation at the current position. Since expired points are removed immediately and dominated candidates are discarded, every point is considered exactly once while preserving correctness.

Python Solution

from collections import deque
from typing import List

class Solution:
    def findMaxValueOfEquation(self, points: List[List[int]], k: int) -> int:
        candidate_points = deque()
        best_answer = float("-inf")

        for x, y in points:
            # Remove points outside distance k
            while candidate_points and x - candidate_points[0][0] > k:
                candidate_points.popleft()

            # Compute equation value
            if candidate_points:
                best_answer = max(
                    best_answer,
                    x + y + candidate_points[0][1]
                )

            current_value = y - x

            # Maintain decreasing order of (y - x)
            while candidate_points and candidate_points[-1][1] <= current_value:
                candidate_points.pop()

            candidate_points.append((x, current_value))

        return best_answer

The implementation follows the algorithm directly.

We first create a deque to store candidate points. Each entry contains the x-coordinate and the transformed value (y - x).

For every point, we first remove expired candidates from the front. Since points are sorted by x-coordinate, once a point becomes invalid, it can never become valid again.

After pruning invalid points, we use the front of the deque to compute the equation. Because the deque is maintained in decreasing order of (y - x), the front always represents the best possible candidate.

Before inserting the current point, we remove weaker candidates from the back. If the current point has a larger or equal (y - x), any smaller value becomes permanently dominated and never useful again.

Finally, we append the current point and continue.

Go Solution

func findMaxValueOfEquation(points [][]int, k int) int {
	type pair struct {
		x     int
		value int // y - x
	}

	deque := make([]pair, 0)
	bestAnswer := -(1 << 60)

	for _, point := range points {
		x, y := point[0], point[1]

		// Remove expired points
		for len(deque) > 0 && x-deque[0].x > k {
			deque = deque[1:]
		}

		// Compute equation value
		if len(deque) > 0 {
			candidate := x + y + deque[0].value
			if candidate > bestAnswer {
				bestAnswer = candidate
			}
		}

		currentValue := y - x

		// Maintain decreasing order
		for len(deque) > 0 &&
			deque[len(deque)-1].value <= currentValue {
			deque = deque[:len(deque)-1]
		}

		deque = append(deque, pair{
			x:     x,
			value: currentValue,
		})
	}

	return bestAnswer
}

The Go implementation mirrors the Python solution closely. Since Go does not provide a built-in deque, we simulate one using a slice.

Removing from the front is done using slicing:

deque = deque[1:]

The integer range in Go is sufficient for this problem because the maximum possible result remains within 32-bit bounds, but using a very negative initialization value like -(1 << 60) ensures correctness without overflow concerns.

Worked Examples

Example 1

Input:

points = [[1,3],[2,0],[5,10],[6,-10]]
k = 1

We track:

  • deque = (x, y - x)
  • answer = maximum equation value
Step Point (x,y) Deque Before Valid Best Equation Value Deque After Answer
1 (1,3) [] none none [(1,2)] -∞
2 (2,0) [(1,2)] (1,2) 2 + 0 + 2 = 4 [(1,2),(2,-2)] 4
3 (5,10) [(1,2),(2,-2)] none, expired none [(5,5)] 4
4 (6,-10) [(5,5)] (5,5) 6 - 10 + 5 = 1 [(5,5),(6,-16)] 4

Final answer:

4

Example 2

Input:

points = [[0,0],[3,0],[9,2]]
k = 3
Step Point (x,y) Deque Before Valid Best Equation Value Deque After Answer
1 (0,0) [] none none [(0,0)] -∞
2 (3,0) [(0,0)] (0,0) 3 + 0 + 0 = 3 [(3,-3)] 3
3 (9,2) [(3,-3)] none, expired none [(9,-7)] 3

Final answer:

3

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each point enters and leaves the deque at most once
Space O(n) The deque may store up to n candidate points

The algorithm is linear because every point is appended to the deque exactly once and removed at most once. Although there are nested while loops, the total number of removals across the entire execution is bounded by n, making the amortized runtime O(n).

Test Cases

class Solution:
    def findMaxValueOfEquation(self, points, k):
        from collections import deque

        dq = deque()
        ans = float("-inf")

        for x, y in points:
            while dq and x - dq[0][0] > k:
                dq.popleft()

            if dq:
                ans = max(ans, x + y + dq[0][1])

            curr = y - x

            while dq and dq[-1][1] <= curr:
                dq.pop()

            dq.append((x, curr))

        return ans

sol = Solution()

assert sol.findMaxValueOfEquation(
    [[1,3],[2,0],[5,10],[6,-10]], 1
) == 4  # Example 1

assert sol.findMaxValueOfEquation(
    [[0,0],[3,0],[9,2]], 3
) == 3  # Example 2

assert sol.findMaxValueOfEquation(
    [[1,1],[2,2]], 10
) == 4  # Minimum valid input size

assert sol.findMaxValueOfEquation(
    [[1,-5],[2,-2],[3,-1]], 2
) == -1  # Negative y-values

assert sol.findMaxValueOfEquation(
    [[1,10],[100,20]], 99
) == 129  # Large x difference still valid

assert sol.findMaxValueOfEquation(
    [[1,5],[2,3],[3,100],[4,2]], 3
) == 106  # Better later point dominates earlier

assert sol.findMaxValueOfEquation(
    [[0,0],[1,0],[2,0],[3,0]], 1
) == 1  # Only adjacent points valid

assert sol.findMaxValueOfEquation(
    [[1,2],[2,4],[3,6],[4,8]], 10
) == 13  # Increasing values

assert sol.findMaxValueOfEquation(
    [[-10,5],[0,10],[5,-5]], 20
) == 25  # Negative x-values
Test Why
Example 1 Validates provided example
Example 2 Validates second example
Two points only Minimum input size
Negative y-values Ensures negative scoring works
Large x difference Verifies k boundary handling
Dominating candidate Tests monotonic deque removal
Adjacent only valid Verifies expiration logic
Increasing sequence Tests larger optimal pair
Negative x-values Ensures coordinate signs are handled correctly

Edge Cases

Only One Valid Pair Exists

Sometimes only a single pair satisfies the distance constraint. A naive implementation might accidentally miss it due to improper window maintenance. Since the deque removes expired points only when x - old_x > k, the implementation preserves all valid candidates and guarantees the lone valid pair is evaluated.

Negative Values in Coordinates

The equation may produce negative results when y values are negative. An incorrect implementation might initialize the answer to 0, which would fail in such situations. This solution initializes the answer to negative infinity, ensuring even entirely negative outcomes are handled correctly.

Large Valid Windows

When k is very large, many points remain valid simultaneously. Without pruning dominated candidates, performance could degrade significantly. The monotonic deque removes weaker candidates immediately, ensuring only potentially optimal points remain and preserving linear complexity.

Expired Candidates at the Front

A subtle bug occurs if expired points are not removed before computing the equation. This could incorrectly use an invalid point whose x-distance exceeds k. The implementation explicitly removes expired points first, guaranteeing every computed equation satisfies the constraint.