A move consists of taking a point (x, y) and transforming it to either (x, X+y) or (X+y, y).
Given A starting point (SX, SY) and a target point (TX, Ty), return True if and only if a sequence of moves exists to Tran Sform the point (SX, SY) to (TX, Ty). Otherwise, return False.
Examples:
input:sx = 1, sy = 1, tx = 3, Ty = 5
output:true
Explanation: One
series of moves that TRANSFO RMS the starting point to the target is: (
1, 1), (1, 2)
(1, 2), (3, 2) (3, 2)--(3, 5)
Input : SX = 1, sy = 1, tx = 2, Ty = 2
output:false
input:sx = 1, sy = 1, tx = 1, ty = 1
output:true
NOTE:SX, Sy, TX, ty'll all is integers in the range [1, 10^9]. This problem is mainly to find the time complexity of the idea of a smaller. No matter how I do, or tle, or stackoverflow, helpless, can only look at solutions, see the solution of the great God.
Solutions:https://leetcode.com/problems/reaching-points/solution/,solutions The first few give is the solution of tle, that is, cannot pass the test case. The main is to see the last AC solution.
approach #1: Exhaustive Search [time Limit exceeded]
Class Solution {public
boolean reachingpoints (int sx, int sy, int tx, int ty) {
if (SX > TX | | sy > TY) ret Urn false;
if (SX = = TX && Sy = = ty) return true;
Return reachingpoints (Sx+sy, Sy, TX, ty) | | Reachingpoints (SX, Sx+sy, TX, ty);
}
}
Complexity analysis
Time Complexity:o (2^{tx + ty}) O (2 tx+ty), a loose bound found by considering every move as (x, Y)--(x+1, y) or (x, Y)--(x, y+1) instead.
Space Complexity:o (TX * ty) O (tx∗ty), the size of the implicit call stack. approach #2: Dynamic programming [Time Limit exceeded]
Intuition and algorithm
As in approach #1, we search for the children of every point recursively, except we use a set seen so, we don ' t repeat wor K.
Import Java.awt.Point;
Class Solution {
set<point> seen;
int TX, Ty;
public boolean reachingpoints (int sx, int sy, int tx, int ty) {
seen = new HashSet ();
This.tx = TX;
This.ty = ty;
Search (new Point (SX, SY));
Return Seen.contains (New Point (TX, Ty));
}
public void Search (point p) {
if (Seen.contains (P)) return;
if (p.x > TX | | p.y > Ty) return;
Seen.add (P);
Search (new Point (p.x + p.y, p.y));
Search (new Point (p.x, p.x + p.y));
}
}
Complexity analysis
Time Complexity:o (TX * ty) O (tx∗ty), as at the most TX * ty points is searched once per point.
Space Complexity:o (TX * ty) O (tx∗ty), the size of the implicit call stack. approach #3: Work backwards (Naive Variant) [Time Limit exceeded]
Intuition
Every parent point (x, y) has a children, (x, X+y) and (X+y, y). However, every point (x, y) is only have one parent candidate (XY, y) if x >= y, Else (x, y-x). This is because we never has points with negative coordinates.
Looking at previous successive parents of the "target point" we can find whether the starting point is an ancestor. For example, if the target is (), the successive parents must has been (7, 5), and (2, 5); So (2, 5) was a starting point of (19, 12).
Algorithm
Repeatedly subtract the smaller of {tx, ty} from the larger of {TX, ty}. The answer is true if and only if we eventually reach SX, Sy.
Class Solution {public
boolean reachingpoints (int sx, int sy, int. TX, int ty) {while
(TX >= SX && ty >= sy) {
if (sx = = TX && Sy = = ty)
return true;
if (tx > Ty) tx-= Ty;
else ty-= TX;
}
return false;
}
}
Complexity analysis
Time Complexity:o (\max (TX, Ty)) O (Max (tx,ty)). If say Ty = 1, we could be subtracting TX times.
Space complexity:o (1) O (1). approach #4: Work backwards (Modulo Variant) [Accepted]
Intuition
As in approach #3, we work backwards to find the answer, trying to transform the target points to the starting point via AP Plying the parent operation (x, y) or (x, y-x) [depending on which one doesn ' t has negative coordinates.]
We can speed up this transformation.
Algorithm
When tx > Ty is found, the parent's operation is tx-ty until tx = tx% Ty. When tx > Ty and ty > sy are satisfied, we can use TX%= ty instead of while tx > TY:TX = ty, which will be faster.
When tx > ty and ty = sy, we know that Ty can no longer be reduced, so only TX will change and will only be changed by subtracting Ty one step at a time. Therefore, using (TX-SX)% Ty = = 0 will be more efficient.
Ty > TX are in the same situation. You can do this all the time until tx = = Ty, and you don't need to move anymore.
Class Solution {public
boolean reachingpoints (int sx, int sy, int. TX, int ty) {while
(TX >= SX && ty >= sy) {
if (tx = = ty) break;
if (tx > Ty) {
if (Ty > Sy) tx%= ty;
else return (tx-sx)% Ty = = 0;
} else {
if (tx > SX) ty%= tx;
else return (ty-sy)% tx = = 0;
}
}
return (tx = = SX && ty = = sy);}
}
Complexity analysis
Time Complexity:o (\log (\max{(TX, Ty)})) O (log (max (tx,ty))). The analysis was similar to the an analysis of the Euclidean algorithm, and we assume that the modulo operation can be do in O (1) O (1) time.
Space complexity:o (1) O (1).