You are given the coordinates of a point (x, y)
and an array points
where each element is also a pair of coordinates [a, b]
. Your task is to find the index of the nearest point in points
that has either the same x-coordinate or the same y-coordinate as (x, y)
. The distance is measured using the Manhattan distance, defined as |x - a| + |y - b|
.
-1
.points
(unless allowed by the problem statement).
Constraints:
1 <= points.length <= 10^4
points[i].length == 2
-10^4 <= x, y, a, b <= 10^4
The main challenge is to efficiently find the point that shares either the x or y coordinate with the target and is closest in Manhattan distance. A brute-force approach would be to check every point in the list, but we should also consider if there's a way to optimize by pre-filtering or using data structures.
For this problem, the brute-force method is simple and effective, but it's important to reason about why it's sufficient and when optimizations might be necessary.
Let's break down the algorithm step by step:
min_distance
to a very large value (like infinity).result_index
to -1
to indicate "not found" by default.points
array:
points[i] = [a, b]
, check if a == x
or b == y
.distance = |x - a| + |y - b|
.distance < min_distance
, update min_distance
and result_index
to the current index.distance == min_distance
but current index is smaller, update result_index
.result_index
.
This approach is efficient because it only requires a single pass through the points
array and uses constant extra space.
Given:
x = 3, y = 4
points = [[1,2],[3,1],[2,4],[2,3],[4,4]]
[1,2]
: x ≠ 3, y ≠ 4 → skip[3,1]
: x = 3 → valid. Distance = |3-3| + |4-1| = 3. min_distance = 3, result_index = 1[2,4]
: y = 4 → valid. Distance = |3-2| + |4-4| = 1. min_distance = 1, result_index = 2[2,3]
: x ≠ 3, y ≠ 4 → skip[4,4]
: y = 4 → valid. Distance = |3-4| + |4-4| = 1. min_distance = 1, but result_index stays 2 since 2 < 4.
Final output: 2
(the index of [2,4]
).
O(N)
where N is the number of points, since we check each point once.O(1)
extra space, as we only track a few variables.This problem demonstrates how a direct, linear scan can be both simple and optimal when constraints are reasonable. The key insights are:
class Solution:
def nearestValidPoint(self, x: int, y: int, points: List[List[int]]) -> int:
min_distance = float('inf')
result_index = -1
for i, (a, b) in enumerate(points):
if a == x or b == y:
distance = abs(x - a) + abs(y - b)
if distance < min_distance:
min_distance = distance
result_index = i
return result_index
class Solution {
public:
int nearestValidPoint(int x, int y, vector<vector<int>>& points) {
int min_distance = INT_MAX;
int result_index = -1;
for (int i = 0; i < points.size(); ++i) {
int a = points[i][0], b = points[i][1];
if (a == x || b == y) {
int distance = abs(x - a) + abs(y - b);
if (distance < min_distance) {
min_distance = distance;
result_index = i;
}
}
}
return result_index;
}
};
class Solution {
public int nearestValidPoint(int x, int y, int[][] points) {
int minDistance = Integer.MAX_VALUE;
int resultIndex = -1;
for (int i = 0; i < points.length; i++) {
int a = points[i][0], b = points[i][1];
if (a == x || b == y) {
int distance = Math.abs(x - a) + Math.abs(y - b);
if (distance < minDistance) {
minDistance = distance;
resultIndex = i;
}
}
}
return resultIndex;
}
}
var nearestValidPoint = function(x, y, points) {
let minDistance = Infinity;
let resultIndex = -1;
for (let i = 0; i < points.length; i++) {
const [a, b] = points[i];
if (a === x || b === y) {
const distance = Math.abs(x - a) + Math.abs(y - b);
if (distance < minDistance) {
minDistance = distance;
resultIndex = i;
}
}
}
return resultIndex;
};