Given four integers sx
, sy
, tx
, and ty
, return true
if it is possible to convert the point (sx, sy)
to the point (tx, ty)
through some operations, or false
otherwise.
The allowed operation on some point (x, y)
is to convert it to either (x, x + y)
or (x + y, y)
.
Example 1:
Input: sx = 1, sy = 1, tx = 3, ty = 5 Output: true Explanation: One series of moves that transforms the starting point to the target is: (1, 1) -> (1, 2) (1, 2) -> (3, 2) (3, 2) -> (3, 5)
Example 2:
Input: sx = 1, sy = 1, tx = 2, ty = 2 Output: false
Example 3:
Input: sx = 1, sy = 1, tx = 1, ty = 1 Output: true
Constraints:
1 <= sx, sy, tx, ty <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to this problem is like trying to get to a specific location on a map by randomly exploring all possible routes. We'll start from the beginning and keep exploring different paths until we find the destination, or exhaust all possible paths.
Here's how the algorithm would work step-by-step:
def reaching_points_brute_force(
start_x, start_y, target_x, target_y
):
visited_points = set()
def explore(current_x, current_y):
# If we've reached the target, return True.
if current_x == target_x and current_y == target_y:
return True
# If we go over target or revisit, stop.
if (
current_x > target_x
or current_y > target_y
or (current_x, current_y) in visited_points
):
return False
visited_points.add((current_x, current_y))
# Explore moving only in the x direction.
if explore(current_x + current_y, current_y):
return True
# Explore moving only in the y direction.
if explore(current_x, current_y + current_x):
return True
return False
return explore(start_x, start_y)
Instead of starting at the beginning and trying to reach the target, the optimal solution works backward from the target. By repeatedly subtracting the smaller value from the larger, we effectively reverse the transformation process. This allows us to reach the starting point more efficiently.
Here's how the algorithm would work step-by-step:
def reaching_points(start_x, start_y, target_x, target_y):
while target_x >= start_x and target_y >= start_y:
if target_x == start_x and target_y == start_y:
return True
if target_x > target_y:
# Reduce target_x by target_y
if target_y == start_y:
return (target_x - start_x) % start_y == 0
target_x %= target_y
else:
# Reduce target_y by target_x
if target_x == start_x:
return (target_y - start_y) % start_x == 0
target_y %= target_x
return False
Case | How to Handle |
---|---|
sx > tx or sy > ty | Return false immediately, as we can only increase the values. |
sx == tx and sy == ty | Return true immediately as the start and target are the same. |
tx == sx and ty > sy | Check if (ty - sy) % sx == 0 to see if it can be reached by repeated (x, x+y) transforms. |
ty == sy and tx > sx | Check if (tx - sx) % sy == 0 to see if it can be reached by repeated (x+y, y) transforms. |
sx or sy are very large (close to max integer) | Consider potential integer overflow during intermediate calculations and use appropriate data types. |
tx and ty are equal | The algorithm needs to handle cases where both target values are the same after some transformations. |
The algorithm gets stuck in a loop | The reverse calculation approach avoids loops. |
tx or ty reaches zero or negative values during the calculation | This should not happen if starting from positive sx and sy and moving backwards, but check to be sure. |