780. Reaching Points [hard]
Problem Description:
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 transform the point (sx, sy) to (tx, ty). Otherwise, return False.
Solution:
A simple recursive solution is that
reachingPoints(sx, sy, tx, ty) = reachingPoints(sx + sy, sy, tx, ty) || reachingPoints(sx, sx + sy, tx, ty)
However, the time complexity is huge so that it needs to be pruned. From top to bottom seems better:
reachingPoints(sx, sy, tx, ty) = reachingPoints(sx + sy, sy, tx - ty, ty)
Here I only consider the situation where tx > ty
. However, this still fails when it happens to (1, 1) -> (1, 1000000)
due to the huge search time.
Thus we can add an important condition to speed up:
if (tx == sx && (ty - sy) % sx == 0) return true;
else if (ty == sy && (tx - sx) % sy == 0) return true;
Hence, my final code is:
class Solution {
public:
bool reachingPoints(int sx, int sy, int tx, int ty) {
if (tx == sx || ty == sy) {
if (tx == sx && (ty - sy) % sx == 0) return true;
else if (ty == sy && (tx - sx) % sy == 0) return true;
else return false;
}
if (tx < sx || ty < sy) return false;
if (sx == tx && sy == ty) return true;
if (tx > ty) return reachingPoints(sx, sy, tx - ty, ty);
return reachingPoints(sx, sy, tx, ty - tx);
}
};
Accepted within 5ms.