Given four integers sx, sy, tx, and ty, return trueif it is possible to convert the point(sx, sy)to the point(tx, ty)through some operations_, or_ falseotherwise.
The allowed operation on some point (x, y) is to convert it to either (x, x + y) or (x + y, y).
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:
1
2
Input: sx = 1, sy = 1, tx = 2, ty = 2
Output: false
Example 3:
1
2
Input: sx = 1, sy = 1, tx = 1, ty = 1
Output: true
At each point (x, y), we have two possible moves: either add y to x (resulting in (x + y, y)) or add x to y (resulting in (x, x + y)). This means that from any starting point, the set of reachable points forms a binary tree, where each node branches into two possible next points. The goal is to determine if there exists a sequence of such moves that transforms (sx, sy) into (tx, ty).
The process can be visualized as a binary tree, where each node represents a possible state (x, y), and each branch corresponds to one of the two allowed moves.
---
title: sx=1, sy=1, tx=3, ty=5
---
graph TD
A(1,1)
B(2,1)
C(1,2)
D(3,1)
E(2,3)
F(1,3)
G(3,2)
H(2,5)
I(1,5)
J(5,1)
K(3,5):::green
L(5,2)
A -- "+y" --> B
A -- "+x" --> C
B -- "+y" --> D
B -- "+x" --> E
C -- "+y" --> F
C -- "+x" --> G
E -- "+y" --> H
F -- "+x" --> I
D -- "+y" --> J
G -- "+y" --> K
G -- "+x" --> L
classDef green fill:#3CB371,stroke:#000,stroke-width:1px,color:#fff;
The height of binary tree depends on tx,ty. All the values which are either greater then tx or ty will be discarded as from that we can’t reach the tx,ty.
Hence, the height of tree would be Max(tx,ty)= N ..total complexity O(2^N)
Method 2 – Iterative Solution (Modulo from the End)#
Instead of building the tree from the starting point (sx, sy), which leads to exponential branching, we can work backwards from the target (tx, ty). At each step, only one parent is possible, so the path is unique. This allows us to efficiently check if the target can be reduced to the start using reverse operations. The key insight is that, by using modulo, we can “jump” back multiple steps at once, avoiding time limit exceeded errors from repeated subtraction.
Start from (tx, ty) and repeatedly subtract the smaller coordinate from the larger, simulating the reverse of the allowed moves.
If tx > ty, set tx = tx % ty; if ty > tx, set ty = ty % tx.
Continue until either tx < sx or ty < sy.
Check for Reachability:
If we reach a point where one coordinate matches the start, check if the other can be reached by repeated additions (i.e., the difference is divisible by the start coordinate).
Efficiency:
Using modulo instead of repeated subtraction makes the algorithm efficient, reducing the time complexity to logarithmic in the size of the target.
Note:
This approach is closely related to the Euclidean algorithm for finding the greatest common divisor (GCD), as both use repeated modulo operations to reduce the problem size efficiently.
Consider node [1,2] as the left child of [1,1] in the tree above.
We reach the base case: [1,2] can be reached from [1,1] if ty >= sy (2 > 1) and (ty - sy) % sx == 0 (since (2-1)%1 == 0).
Why (ty - sy) % sx == 0?
Because sy can only reach ty by repeated additions of sx (i.e., sy + k*sx = ty for some integer k). Thus, (ty - sy) / sx must be an integer, so the remainder is zero.
classSolution {
publicbooleanreachingPoints(int sx, int sy, int tx, int ty) {
while (tx > sx && ty > sy) {
if (tx > ty) tx %= ty;
else ty %= tx;
}
if (sx == tx && sy <= ty && (ty - sy) % sx == 0) returntrue;
if (sy == ty && sx <= tx && (tx - sx) % sy == 0) returntrue;
returnfalse;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution {
funreachingPoints(sx: Int, sy: Int, tx: Int, ty: Int): Boolean {
var tx = tx
var ty = ty
while (tx > sx && ty > sy) {
if (tx > ty) tx %= ty
else ty %= tx
}
if (sx == tx && sy <= ty && (ty - sy) % sx ==0) returntrueif (sy == ty && sx <= tx && (tx - sx) % sy ==0) returntruereturnfalse }
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defreachingPoints(self, sx: int, sy: int, tx: int, ty: int) -> bool:
while tx > sx and ty > sy:
if tx > ty:
tx %= ty
else:
ty %= tx
if sx == tx and sy <= ty and (ty - sy) % sx ==0:
returnTrueif sy == ty and sx <= tx and (tx - sx) % sy ==0:
returnTruereturnFalse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnreaching_points(sx: i32, sy: i32, mut tx: i32, mut ty: i32) -> bool {
while tx > sx && ty > sy {
if tx > ty {
tx %= ty;
} else {
ty %= tx;
}
}
if sx == tx && sy <= ty && (ty - sy) % sx ==0 {
returntrue;
}
if sy == ty && sx <= tx && (tx - sx) % sy ==0 {
returntrue;
}
false }
}
1
2
3
4
5
6
7
8
9
10
11
12
functionreachingPoints(sx: number, sy: number, tx: number, ty: number):boolean {
while (tx>sx&&ty>sy) {
if (tx>ty) {
tx%=ty;
} else {
ty%=tx;
}
}
if (sx===tx&&sy<=ty&& (ty-sy) %sx===0) returntrue;
if (sy===ty&&sx<=tx&& (tx-sx) %sy===0) returntrue;
returnfalse;
}