Determine if a Cell Is Reachable at a Given Time
MedPrompt
You are given four integers sx, sy, fx, fy, and a non-negative integer t.
In an infinite 2D grid, you start at the cell (sx, sy). Each second, you must move to any of its adjacent cells.
Return true if you can reach cell (fx, fy) after exactly t seconds, or false otherwise.
A cell's adjacent cells are the 8 cells around it that share at least one corner with it. You can visit the same cell several times.
Example 1:
Input: sx = 2, sy = 4, fx = 7, fy = 7, t = 6
Output: true
Explanation: Starting at cell (2, 4), we can reach cell (7, 7) in exactly 6 seconds by going through the cells depicted in the picture above. Example 2:
Input: sx = 3, sy = 1, fx = 7, fy = 3, t = 3
Output: false
Explanation: Starting at cell (3, 1), it takes at least 4 seconds to reach cell (7, 3) by going through the cells depicted in the picture above. Hence, we cannot reach cell (7, 3) at the third second.
Constraints:
1 <= sx, sy, fx, fy <= 1090 <= t <= 109
Approaches
2 approaches with complexity analysis and trade-offs.
This approach simulates the process of moving on the grid step by step. We can use a Breadth-First Search (BFS) to explore all possible cells reachable at each second, from 1 to t. We start at (sx, sy) at time 0. At each second, we explore all 8 adjacent cells from the cells we could reach in the previous second. If at exactly time t, one of the reachable cells is (fx, fy), we return true.
Algorithm
- Initialize a queue and add the starting state
(sx, sy, 0). - Initialize a set
visitedto store(x, y, time)tuples to avoid redundant exploration. Add(sx, sy, 0)tovisited. - While the queue is not empty:
- Dequeue the current state
(x, y, time). - If
time == t:- If
x == fxandy == fy, returntrue. - Continue to the next state in the queue.
- If
- If
time > t, stop exploring this path. - For each of the 8 neighbors
(nx, ny)of(x, y):- If
(nx, ny, time + 1)is not invisited:- Add
(nx, ny, time + 1)tovisited. - Enqueue
(nx, ny, time + 1).
- Add
- If
- Dequeue the current state
- If the loop finishes, it means
(fx, fy)was not reached at exactly timet. Returnfalse.
Walkthrough
The state in our search can be represented by (x, y, time). We start with a queue containing the initial state (sx, sy, 0). We also need a way to keep track of visited states (x, y, time) to avoid cycles and redundant work. A hash set is needed due to the large coordinate values.
The BFS proceeds level by level, where each level corresponds to one second of time. In each step, we dequeue a state (curr_x, curr_y, curr_time). If curr_time == t, we check if we are at the destination. If curr_time < t, we generate all 8 adjacent cells and enqueue them for the next time step if they haven't been visited at that specific time. This approach is not feasible given the constraints t <= 10^9 because the number of reachable cells grows exponentially with time.
Complexity
Time
O(8^t). At each step `k`, we can reach up to `8^k` new cells.
Space
O(8^t). The queue and visited set can grow exponentially.
Trade-offs
Pros
Conceptually simple and directly models the problem statement.
Cons
Extremely inefficient. The time and space complexity are exponential in
t, making it infeasible for the given constraints.tcan be up to10^9, so a simulation is impossible.Storing visited states with large coordinates requires a hash-based set, which has overhead.
Instead of simulating the movement, we can solve this problem by analyzing the properties of movement on the grid. The key insight is to determine the minimum time required to travel between the start and end cells and then consider how any extra time can be spent.
Algorithm
- Calculate the horizontal distance
dx = |sx - fx|. - Calculate the vertical distance
dy = |sy - fy|. - Check for the special case where the start and end points are the same (
dx == 0anddy == 0).- If they are the same, return
trueiftis not equal to 1, andfalseotherwise. This is because we must move each second, so we can't stay at the same spot att=1. Fort=0we are already there, and fort>=2we can move away and come back.
- If they are the same, return
- If the points are different, calculate the minimum time required, which is the Chebyshev distance:
min_time = max(dx, dy). - Return
trueif the given timetis greater than or equal tomin_time, andfalseotherwise. Any timet >= min_timeis achievable.
Walkthrough
The minimum number of moves to get from (sx, sy) to (fx, fy) is determined by the Chebyshev distance, which is max(|sx - fx|, |sy - fy|). This is because in one move (one second), we can cover at most one unit of distance in the x-direction and one unit in the y-direction (with a diagonal move). To cover a total horizontal distance of dx = |sx - fx| and vertical distance of dy = |sy - fy|, we need at least max(dx, dy) moves. Let this be min_time.
The problem can be broken down into two main cases:
-
Start and Finish cells are the same (
sx = fx,sy = fy):- In this case,
dx = 0anddy = 0, somin_time = 0. - If
t = 0, we are already at the destination. It's possible. - If
t = 1, we must move to an adjacent cell, so we cannot be at the starting cell. It's impossible. - If
t >= 2, we can spend the time by moving to an adjacent cell and then moving back. This takes 2 seconds. It's possible for anytexceptt=1.
- In this case,
-
Start and Finish cells are different:
- The minimum time required is
min_time = max(dx, dy). - If the given time
tis less thanmin_time, it's impossible to reach the destination. - If
t >= min_time, we can always reach the destination. We can arrive inmin_timeseconds using an optimal path. Any extra timet - min_timecan be "wasted" by taking small detours or moving back-and-forth from the destination. Thus, ift >= min_time, it's always possible.
- The minimum time required is
Combining these observations gives a simple and efficient algorithm.
class Solution { public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) { int dx = Math.abs(sx - fx); int dy = Math.abs(sy - fy); if (dx == 0 && dy == 0) { // If start and end are the same, we can't reach in exactly 1 second // because we must move. For any other time t != 1, it's possible. return t != 1; } int minTime = Math.max(dx, dy); // If we are not at the same cell, we must take at least minTime steps. return t >= minTime; }}Complexity
Time
O(1). The solution involves a few arithmetic operations and comparisons, which take constant time.
Space
O(1). No extra space is used that depends on the input size.
Trade-offs
Pros
Extremely efficient with constant time and space complexity.
Handles all edge cases correctly.
Works for the large constraints given in the problem.
Cons
The logic is not immediately obvious and requires some mathematical reasoning about grid movement.
Solutions
Solution
public class Solution { public bool IsReachableAtTime(int sx, int sy, int fx, int fy, int t) { if (sx == fx && sy == fy) return t != 1; return Math.Max(Math.Abs(sx - fx), Math.Abs(sy - fy)) <= t; }}class Solution {public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) { if (sx == fx && sy == fy) { return t != 1; } int dx = Math.abs(sx - fx); int dy = Math.abs(sy - fy); return Math.max(dx, dy) <= t; }}class Solution: def isReachableAtTime(self, sx: int, sy: int, fx: int, fy: int, t: int) -> bool: if sx == fx and sy == fy: return t != 1 dx = abs(sx - fx) dy = abs(sy - fy) return max(dx, dy) <= tclass Solution {public: bool isReachableAtTime(int sx, int sy, int fx, int fy, int t) { if (sx == fx && sy == fy) { return t != 1; } int dx = abs(fx - sx), dy = abs(fy - sy); return max(dx, dy) <= t; }};Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.