2849. Determine if a Cell Is Reachable at a Given Time
Problem Description
You start at position (sx, sy)
on an infinite 2D grid. Your goal is to reach position (fx, fy)
in exactly t
seconds.
Each second, you must move to one of the 8 adjacent cells around your current position. These adjacent cells are the ones that share at least one corner with your current cell (including diagonal moves). You can revisit cells multiple times.
Given the starting coordinates (sx, sy)
, destination coordinates (fx, fy)
, and a non-negative integer t
representing the time limit, determine if it's possible to reach the destination in exactly t
seconds.
The function should return true
if you can reach (fx, fy)
after exactly t
seconds, and false
otherwise.
Key Points:
- You must move every second (you cannot stay in place)
- You can move in 8 directions (horizontally, vertically, and diagonally)
- You must use exactly
t
seconds, no more and no less - The grid is infinite, so there are no boundaries
- You can visit the same cell multiple times during your journey
Intuition
The key insight is to find the minimum number of moves required to reach the destination, then determine if we can use exactly t
moves.
Since we can move diagonally, the minimum distance between two points isn't the Manhattan distance, but rather the Chebyshev distance (or chessboard distance). When we can move diagonally, we can cover both x and y distances simultaneously. For example, to go from (0, 0)
to (3, 2)
, we can move diagonally twice (covering 2 units in both x and y), then move once more horizontally. This takes max(3, 2) = 3
moves minimum.
So the minimum moves needed is max(|fx - sx|, |fy - sy|)
.
Once we know the minimum moves required, we need to consider if we can use exactly t
moves:
-
If
t
equals the minimum moves needed: We can reach the destination exactly. -
If
t
is greater than minimum moves: We can reach the destination early and then "waste" the remaining moves. We can do this by moving back and forth between any two adjacent cells. For instance, move right then left repeatedly, or move to any adjacent cell and back. -
Special case - starting point equals destination: If we're already at the destination (
sx == fx
andsy == fy
), the minimum moves is 0. However, since we MUST move every second, we cannot stay put. Ift = 1
, it's impossible (we'd have to move away and can't get back in 1 move). For any othert
value (0, 2, 3, ...), we can move away and come back, using exactlyt
moves.
This leads to our solution: check if the minimum required moves max(|fx - sx|, |fy - sy|)
is less than or equal to t
, with special handling for the case where start equals destination.
Learn more about Math patterns.
Solution Approach
The implementation follows directly from our intuition with a simple case-based approach:
Case 1: Starting point equals destination
When sx == fx
and sy == fy
, we're already at the destination. Since we must move every second:
- If
t = 1
: It's impossible. We'd move away but can't return in just 1 move. - If
t = 0
ort ≥ 2
: It's possible. We can move to an adjacent cell and come back (takes 2 moves), and repeat this pattern as needed.
This is handled by the condition: return t != 1
Case 2: Starting point differs from destination
We calculate the minimum moves required using the Chebyshev distance:
dx = abs(sx - fx)
- absolute difference in x-coordinatesdy = abs(sy - fy)
- absolute difference in y-coordinates- Minimum moves =
max(dx, dy)
Since we can move diagonally, we can cover the shorter distance while simultaneously covering part of the longer distance. The remaining moves will be along the axis with the larger difference.
Finally, we check if max(dx, dy) <= t
:
- If true: We can reach the destination in the minimum required moves, and any extra time can be used to move back and forth between adjacent cells.
- If false: We don't have enough time to reach the destination.
Complete Algorithm:
if sx == fx and sy == fy:
return t != 1
dx = abs(sx - fx)
dy = abs(sy - fy)
return max(dx, dy) <= t
The solution runs in O(1)
time and space complexity, as we only perform constant-time arithmetic operations and comparisons.
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 few examples to illustrate the solution approach:
Example 1: Simple diagonal movement
- Start:
(sx, sy) = (1, 1)
, Destination:(fx, fy) = (3, 4)
, Time:t = 3
- Calculate differences:
dx = |3 - 1| = 2
,dy = |4 - 1| = 3
- Minimum moves needed:
max(2, 3) = 3
- Since
3 ≤ 3
, we can reach the destination in exactly 3 seconds - Path:
(1,1) → (2,2) → (3,3) → (3,4)
- Result:
true
Example 2: Extra time available
- Start:
(sx, sy) = (0, 0)
, Destination:(fx, fy) = (2, 2)
, Time:t = 5
- Calculate differences:
dx = |2 - 0| = 2
,dy = |2 - 0| = 2
- Minimum moves needed:
max(2, 2) = 2
- Since
2 ≤ 5
, we have 3 extra seconds after reaching the destination - Path:
(0,0) → (1,1) → (2,2) → (2,3) → (2,2) → (2,3)
(reach in 2 moves, then oscillate) - Result:
true
Example 3: Not enough time
- Start:
(sx, sy) = (1, 2)
, Destination:(fx, fy) = (7, 9)
, Time:t = 5
- Calculate differences:
dx = |7 - 1| = 6
,dy = |9 - 2| = 7
- Minimum moves needed:
max(6, 7) = 7
- Since
7 > 5
, we don't have enough time to reach the destination - Result:
false
Example 4: Already at destination (special case)
-
Start:
(sx, sy) = (3, 3)
, Destination:(fx, fy) = (3, 3)
, Time:t = 1
-
We're already at the destination, but must move every second
-
With
t = 1
, we'd move away but cannot return in just 1 move -
Result:
false
-
Same scenario with
t = 2
: -
Path:
(3,3) → (3,4) → (3,3)
(move away and come back) -
Result:
true
Solution Implementation
1class Solution:
2 def isReachableAtTime(self, sx: int, sy: int, fx: int, fy: int, t: int) -> bool:
3 """
4 Determines if we can reach from start point (sx, sy) to finish point (fx, fy)
5 in exactly t seconds.
6
7 Movement is allowed in 8 directions: horizontally, vertically, and diagonally.
8 Each move takes 1 second.
9
10 Args:
11 sx: Starting x-coordinate
12 sy: Starting y-coordinate
13 fx: Finishing x-coordinate
14 fy: Finishing y-coordinate
15 t: Time available in seconds
16
17 Returns:
18 True if the finish point is reachable in exactly t seconds, False otherwise
19 """
20
21 # Special case: if start and finish are the same point
22 # We can't reach it in exactly 1 second (we'd need to move away and come back)
23 if sx == fx and sy == fy:
24 return t != 1
25
26 # Calculate the Manhattan distance components
27 x_distance = abs(sx - fx)
28 y_distance = abs(sy - fy)
29
30 # The minimum time needed is the maximum of the two distances
31 # (since we can move diagonally to cover both distances simultaneously)
32 min_time_needed = max(x_distance, y_distance)
33
34 # We can reach the target if we have at least the minimum time needed
35 # Extra time can be used to make additional moves (move away and come back)
36 return min_time_needed <= t
37
1class Solution {
2 public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) {
3 // Special case: if starting and ending positions are the same
4 // We cannot reach the same position in exactly 1 second (must stay or move away and back)
5 if (sx == fx && sy == fy) {
6 return t != 1;
7 }
8
9 // Calculate the horizontal distance between start and finish
10 int horizontalDistance = Math.abs(sx - fx);
11
12 // Calculate the vertical distance between start and finish
13 int verticalDistance = Math.abs(sy - fy);
14
15 // The minimum time needed is the maximum of horizontal and vertical distances
16 // This is because we can move diagonally (covering both x and y simultaneously)
17 // until one dimension is aligned, then move straight for the remaining distance
18 int minimumTimeRequired = Math.max(horizontalDistance, verticalDistance);
19
20 // Check if we have enough time to reach the destination
21 return minimumTimeRequired <= t;
22 }
23}
24
1class Solution {
2public:
3 bool isReachableAtTime(int sx, int sy, int fx, int fy, int t) {
4 // Special case: starting and ending at the same position
5 // Cannot reach in exactly 1 second (must move away and come back)
6 if (sx == fx && sy == fy) {
7 return t != 1;
8 }
9
10 // Calculate the absolute distance in x and y directions
11 int distanceX = abs(fx - sx);
12 int distanceY = abs(fy - sy);
13
14 // The minimum time needed is the maximum of the two distances
15 // (can move diagonally, so we can cover both x and y simultaneously)
16 int minimumTime = max(distanceX, distanceY);
17
18 // Check if we have enough time to reach the destination
19 return minimumTime <= t;
20 }
21};
22
1/**
2 * Determines if it's possible to reach from starting position to final position in exactly t seconds.
3 * Movement is allowed in 8 directions (horizontally, vertically, and diagonally).
4 * Each move takes 1 second.
5 *
6 * @param sx - Starting x-coordinate
7 * @param sy - Starting y-coordinate
8 * @param fx - Final/target x-coordinate
9 * @param fy - Final/target y-coordinate
10 * @param t - Time available in seconds
11 * @returns true if the target can be reached in exactly t seconds, false otherwise
12 */
13function isReachableAtTime(sx: number, sy: number, fx: number, fy: number, t: number): boolean {
14 // Special case: if starting and ending positions are the same
15 // We can't stay in place for exactly 1 second (need at least 2 seconds to move away and back)
16 if (sx === fx && sy === fy) {
17 return t !== 1;
18 }
19
20 // Calculate the horizontal distance between start and end points
21 const horizontalDistance: number = Math.abs(sx - fx);
22
23 // Calculate the vertical distance between start and end points
24 const verticalDistance: number = Math.abs(sy - fy);
25
26 // The minimum time needed is the maximum of horizontal and vertical distances
27 // (since we can move diagonally to cover both distances simultaneously)
28 // We can reach the target if we have at least this minimum time
29 return Math.max(horizontalDistance, verticalDistance) <= t;
30}
31
Time and Space Complexity
The time complexity is O(1)
because the algorithm performs a fixed number of operations regardless of the input size. It only involves:
- Two equality comparisons (
sx == fx
andsy == fy
) - One inequality comparison (
t != 1
) - Two absolute value calculations (
abs(sx - fx)
andabs(sy - fy)
) - One
max()
operation between two values - One comparison (
max(dx, dy) <= t
)
All these operations take constant time.
The space complexity is O(1)
because the algorithm only uses a constant amount of extra space. It stores:
- Two integer variables
dx
anddy
No additional data structures are created, and the space usage doesn't depend on the input values.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Forgetting the Special Case When Start Equals Destination
The Problem: Many developers initially write code like this:
def isReachableAtTime(self, sx, sy, fx, fy, t):
x_distance = abs(sx - fx)
y_distance = abs(sy - fy)
min_time_needed = max(x_distance, y_distance)
return min_time_needed <= t
This looks correct at first glance - if we're already at the destination (distance = 0), and we have any time t ≥ 0
, it should return True
. However, this fails for the case where sx == fx
, sy == fy
, and t = 1
.
Why It Fails: When we're already at the destination and have exactly 1 second:
- We MUST move (we can't stay in place)
- After moving to any adjacent cell, we've used our 1 second
- We're now not at the destination, making it impossible
The Solution: Always handle the special case explicitly:
if sx == fx and sy == fy: return t != 1 # Can't reach in exactly 1 second, but any other time is fine
Pitfall 2: Using Manhattan Distance Instead of Chebyshev Distance
The Problem: Some might incorrectly calculate the minimum distance as:
min_time_needed = abs(sx - fx) + abs(sy - fy) # Wrong!
Why It Fails: Manhattan distance assumes you can only move horizontally or vertically, not diagonally. For example:
- From (0, 0) to (3, 3)
- Manhattan distance: 3 + 3 = 6 moves
- Actual minimum with diagonal moves: 3 moves (moving diagonally 3 times)
The Solution: Use Chebyshev distance (maximum of the two coordinate differences):
min_time_needed = max(abs(sx - fx), abs(sy - fy)) # Correct!
Pitfall 3: Thinking Extra Moves Are Impossible
The Problem: Some might think that if the minimum distance is 5 and we have 7 seconds, it's impossible because we have "extra" time:
def isReachableAtTime(self, sx, sy, fx, fy, t):
# Wrong logic: thinking we need EXACTLY the minimum time
min_time_needed = max(abs(sx - fx), abs(sy - fy))
return min_time_needed == t # Wrong!
Why It Fails: We can always use extra time by moving back and forth between adjacent cells. For instance:
- Reach the destination in minimum time
- Move to an adjacent cell
- Move back to the destination
- Repeat as needed to use up remaining time
The Solution: Check if we have AT LEAST the minimum time needed:
return min_time_needed <= t # We can use extra time for back-and-forth moves
Which of the following array represent a max heap?
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!