1266. Minimum Time Visiting All Points
Problem Description
You are given n
points on a 2D plane, where each point is represented as points[i] = [xi, yi]
with integer coordinates. Your task is to find the minimum time in seconds needed to visit all points in the exact order they appear in the array.
The movement rules are:
- In 1 second, you can make one of three moves:
- Move vertically by 1 unit (up or down)
- Move horizontally by 1 unit (left or right)
- Move diagonally by
sqrt(2)
units (which means moving 1 unit vertically and 1 unit horizontally simultaneously)
Key constraints:
- You must visit the points in the given order
- You can pass through points that appear later in the array, but they don't count as visited until you reach them in sequence
The solution leverages the fact that for any two points p1 = (x1, y1)
and p2 = (x2, y2)
, the minimum time to travel between them is max(|x1 - x2|, |y1 - y2|)
. This is because:
- If the horizontal distance
dx = |x1 - x2|
and vertical distancedy = |y1 - y2|
are different, you can move diagonally formin(dx, dy)
seconds (covering both x and y distance simultaneously), then move in the remaining direction for|dx - dy|
seconds - The total time is
min(dx, dy) + |dx - dy| = max(dx, dy)
The solution calculates this maximum distance for each consecutive pair of points and sums them up to get the total minimum time.
Intuition
The key insight comes from understanding how diagonal movement works. Since we can move diagonally (covering both x and y distance in a single second), we should use diagonal moves as much as possible to minimize time.
Let's think about moving from point A to point B. We need to cover some horizontal distance dx
and some vertical distance dy
. Since diagonal movement allows us to cover 1 unit in both x and y directions simultaneously, we can move diagonally for min(dx, dy)
seconds. After these diagonal moves, we've covered equal distances in both directions, but we still have remaining distance in one direction: max(dx, dy) - min(dx, dy)
.
For example, if we need to move 5 units horizontally and 3 units vertically:
- Move diagonally for 3 seconds (covers 3 units in both x and y)
- Move horizontally for 2 more seconds (covers the remaining 2 units in x)
- Total time: 3 + 2 = 5 seconds, which equals
max(5, 3)
This pattern holds for any two points: the minimum time is always max(dx, dy)
because:
- We use diagonal moves for
min(dx, dy)
seconds - We use straight moves (either horizontal or vertical) for
max(dx, dy) - min(dx, dy)
seconds - Total:
min(dx, dy) + (max(dx, dy) - min(dx, dy)) = max(dx, dy)
Since we must visit points in order, the total minimum time is simply the sum of minimum times between each consecutive pair of points. This gives us the elegant solution: sum up max(|x1 - x2|, |y1 - y2|)
for all consecutive point pairs.
Learn more about Math patterns.
Solution Approach
The implementation follows a straightforward simulation approach based on our understanding that the minimum distance between any two points is max(dx, dy)
.
Algorithm Steps:
-
Iterate through consecutive point pairs: We need to calculate the distance between each consecutive pair of points in the given order. Python's
pairwise()
function makes this elegant by automatically creating pairs(points[0], points[1])
,(points[1], points[2])
, and so on. -
Calculate distance for each pair: For each pair of points
p1 = (x1, y1)
andp2 = (x2, y2)
:- Calculate the horizontal distance:
dx = |p1[0] - p2[0]|
- Calculate the vertical distance:
dy = |p1[1] - p2[1]|
- The minimum time between these points is
max(dx, dy)
- Calculate the horizontal distance:
-
Sum all distances: Since we must visit points in order, the total minimum time is the sum of all individual minimum times between consecutive points.
Implementation Details:
def minTimeToVisitAllPoints(self, points: List[List[int]]) -> int:
return sum(
max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]))
for p1, p2 in pairwise(points)
)
The solution uses:
pairwise(points)
: Creates an iterator of consecutive pairs from the points listabs()
: Computes absolute difference to get distance regardless of directionmax()
: Selects the larger of the two distances (horizontal vs vertical)sum()
: Aggregates all the minimum distances between consecutive points
Time Complexity: O(n)
where n is the number of points, as we visit each point once.
Space Complexity: O(1)
as we only use constant extra space for calculations.
This approach efficiently solves the problem by recognizing that diagonal movement optimization naturally leads to the max(dx, dy)
formula for any two points.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example with points = [[1,1], [3,4], [-1,0]]
.
We need to visit these points in order: (1,1) → (3,4) → (-1,0).
Step 1: Calculate distance from point (1,1) to point (3,4)
- Horizontal distance:
dx = |1 - 3| = 2
- Vertical distance:
dy = |1 - 4| = 3
- Minimum time:
max(2, 3) = 3
seconds
To understand why this is 3 seconds:
- We can move diagonally for 2 seconds (covering 2 units in both x and y directions)
- After 2 diagonal moves: we're at (3,3)
- Then move vertically for 1 more second to reach (3,4)
- Total: 2 + 1 = 3 seconds
Step 2: Calculate distance from point (3,4) to point (-1,0)
- Horizontal distance:
dx = |3 - (-1)| = 4
- Vertical distance:
dy = |4 - 0| = 4
- Minimum time:
max(4, 4) = 4
seconds
Since both distances are equal, we can move diagonally for all 4 seconds:
- 4 diagonal moves take us from (3,4) to (-1,0)
Step 3: Sum all minimum times
- Total time = 3 + 4 = 7 seconds
Using our solution code:
def minTimeToVisitAllPoints(points):
return sum(
max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]))
for p1, p2 in pairwise(points)
)
# With points = [[1,1], [3,4], [-1,0]]
# pairwise creates: ((1,1), (3,4)) and ((3,4), (-1,0))
# First pair: max(|1-3|, |1-4|) = max(2, 3) = 3
# Second pair: max(|3-(-1)|, |4-0|) = max(4, 4) = 4
# Sum: 3 + 4 = 7
The answer is 7 seconds.
Solution Implementation
1class Solution:
2 def minTimeToVisitAllPoints(self, points: List[List[int]]) -> int:
3 """
4 Calculate minimum time to visit all points in order.
5
6 Time is calculated using Chebyshev distance (diagonal moves allowed).
7 The minimum time between two points is the maximum of absolute differences
8 in x and y coordinates.
9
10 Args:
11 points: List of [x, y] coordinates to visit in order
12
13 Returns:
14 Minimum time (seconds) to visit all points
15 """
16 total_time = 0
17
18 # Iterate through consecutive pairs of points
19 for i in range(len(points) - 1):
20 current_point = points[i]
21 next_point = points[i + 1]
22
23 # Calculate absolute differences in x and y coordinates
24 x_distance = abs(current_point[0] - next_point[0])
25 y_distance = abs(current_point[1] - next_point[1])
26
27 # Time needed is the maximum of x and y distances (Chebyshev distance)
28 # This accounts for diagonal movement being allowed
29 time_between_points = max(x_distance, y_distance)
30
31 total_time += time_between_points
32
33 return total_time
34
1class Solution {
2 /**
3 * Calculates the minimum time required to visit all points in order.
4 * Movement is allowed in 8 directions: horizontally, vertically, and diagonally.
5 * Each move takes 1 second.
6 *
7 * @param points 2D array where each element represents a point [x, y]
8 * @return minimum time in seconds to visit all points in order
9 */
10 public int minTimeToVisitAllPoints(int[][] points) {
11 int totalTime = 0;
12
13 // Iterate through consecutive pairs of points
14 for (int i = 1; i < points.length; i++) {
15 // Calculate horizontal distance between current and previous point
16 int horizontalDistance = Math.abs(points[i][0] - points[i - 1][0]);
17
18 // Calculate vertical distance between current and previous point
19 int verticalDistance = Math.abs(points[i][1] - points[i - 1][1]);
20
21 // Minimum time is the maximum of horizontal and vertical distances
22 // This works because we can move diagonally to cover both distances simultaneously
23 // until one is exhausted, then move straight for the remaining distance
24 totalTime += Math.max(horizontalDistance, verticalDistance);
25 }
26
27 return totalTime;
28 }
29}
30
1class Solution {
2public:
3 int minTimeToVisitAllPoints(vector<vector<int>>& points) {
4 int totalTime = 0;
5
6 // Iterate through consecutive pairs of points
7 for (int i = 1; i < points.size(); ++i) {
8 // Calculate the horizontal distance between current and previous point
9 int horizontalDistance = abs(points[i][0] - points[i - 1][0]);
10
11 // Calculate the vertical distance between current and previous point
12 int verticalDistance = abs(points[i][1] - points[i - 1][1]);
13
14 // The minimum time to travel between two points is the maximum of
15 // horizontal and vertical distances (due to diagonal movement capability)
16 // We can move diagonally (1 unit in both x and y) or straight (1 unit in x or y)
17 // So the time required is determined by the larger dimension
18 totalTime += max(horizontalDistance, verticalDistance);
19 }
20
21 return totalTime;
22 }
23};
24
1/**
2 * Calculates the minimum time needed to visit all points in order.
3 * Movement is allowed in 8 directions (horizontal, vertical, and diagonal).
4 * Each move takes 1 second.
5 *
6 * @param points - Array of 2D coordinates [x, y] to visit in order
7 * @returns The minimum time in seconds to visit all points
8 */
9function minTimeToVisitAllPoints(points: number[][]): number {
10 // Initialize total time counter
11 let totalTime: number = 0;
12
13 // Iterate through consecutive point pairs
14 for (let i: number = 1; i < points.length; i++) {
15 // Calculate absolute difference in x-coordinates
16 const deltaX: number = Math.abs(points[i][0] - points[i - 1][0]);
17
18 // Calculate absolute difference in y-coordinates
19 const deltaY: number = Math.abs(points[i][1] - points[i - 1][1]);
20
21 // The minimum time is the maximum of the two distances
22 // (diagonal moves cover both x and y simultaneously)
23 totalTime += Math.max(deltaX, deltaY);
24 }
25
26 return totalTime;
27}
28
Time and Space Complexity
The time complexity is O(n)
, where n
is the number of points. The algorithm iterates through consecutive pairs of points using pairwise(points)
, which generates n-1
pairs from n
points. For each pair, it calculates the maximum of the absolute differences in x and y coordinates, which is a constant time operation O(1)
. Therefore, the overall time complexity is O(n-1) * O(1) = O(n)
.
The space complexity is O(1)
. The pairwise
function is a generator that yields pairs lazily without creating a new list to store all pairs at once. The sum
function accumulates the result using a single variable. The only additional space used is for temporary variables p1
and p2
to hold the current pair of points, which requires constant space regardless of the input size.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Misunderstanding the Distance Formula
A common mistake is trying to use Euclidean distance or Manhattan distance instead of Chebyshev distance. Developers might incorrectly attempt:
- Euclidean distance:
sqrt((x2-x1)^2 + (y2-y1)^2)
- This doesn't account for the fact that diagonal moves take only 1 second - Manhattan distance:
|x2-x1| + |y2-y1|
- This assumes no diagonal movement is possible
Solution: Remember that diagonal movement allows covering both x and y distance simultaneously in 1 second, leading to max(|x2-x1|, |y2-y1|)
.
2. Attempting to Find Optimal Path Across All Points
Some developers mistakenly try to find the globally optimal path visiting all points, treating this as a Traveling Salesman Problem variant. They might attempt dynamic programming or graph algorithms.
Solution: The problem explicitly states points must be visited in the given order. Simply calculate distances between consecutive points.
3. Off-by-One Errors in Loop Iteration
When iterating through point pairs, it's easy to make indexing errors:
# Wrong: Goes out of bounds
for i in range(len(points)):
time += max(abs(points[i][0] - points[i+1][0]), ...) # IndexError when i = len(points)-1
# Wrong: Misses the last pair
for i in range(len(points) - 2): # Should be len(points) - 1
time += max(...)
Solution: Use range(len(points) - 1)
or utilize Python's pairwise()
function for cleaner code.
4. Integer Division or Type Confusion
Some might mistakenly think diagonal distance needs special handling:
# Wrong: Trying to calculate diagonal steps separately
diagonal_steps = min(x_distance, y_distance)
remaining_steps = abs(x_distance - y_distance)
time = diagonal_steps * sqrt(2) + remaining_steps # Incorrect!
Solution: The problem states diagonal movement takes 1 second (not sqrt(2)
seconds), even though it covers sqrt(2)
distance. The time calculation remains max(dx, dy)
.
5. Forgetting to Handle Edge Cases
Not considering arrays with only one point or empty arrays:
# This would fail for single-point arrays
for i in range(len(points) - 1): # Loop doesn't execute if len(points) = 1
# ...
Solution: Single point arrays should return 0 (no movement needed). The standard implementation handles this correctly as the loop simply doesn't execute.
Is the following code DFS or BFS?
void search(Node root) { if (!root) return; visit(root); root.visited = true; for (Node node in root.adjacent) { if (!node.visited) { search(node); } } }
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!