给定四个整数 sx , sy ,tx 和 ty,如果通过一系列的转换可以从起点 (sx,
sy) 到达终点 (tx, ty),则返回 true,否则返回 false。
从点 (x, y) 可以转换到 (x, x+y) 或者 (x+y, y)。
示例:
输入: sx = 1, sy = 1, tx = 3, ty = 5
输出: true
解释:
可以通过以下一系列转换从起点转换到终点:
(1, 1) -> (1, 2)
(1, 2) -> (3, 2)
(3, 2) -> (3, 5)
思路:
我们可以很轻松的想到递归,每次无非就是要么是(sx + sy, sy)
或者(sx, sx + sy)
;
我们可以写出:
1 2 3 4 5 6 7 8
| class Solution { public: bool reachingPoints(int sx, int sy, int tx, int ty) { if(sx > tx || sy > ty) return false; if(sx == tx && sy == ty) return true; return reachingPoints(sx + sy, sy, tx, ty) || reachingPoints(sx, sx + sy, tx, ty); } };
|
然后我们发现栈溢出了,这里可以用long解决,但是肯定超时。
那既然正着求会栈溢出,我们可不可以倒着求呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public: bool reachingPoints(int sx, int sy, int tx, int ty) { if(tx < sx || ty < sy) return false; while(tx > 0 && ty > 0){ if(sx == tx && sy == ty){ return true; } if(tx > ty){ tx -= ty; }else{ ty -= tx; } } return false; } };
|
发现还是超时了,还有哪里可以改进呢,我们发现在tx > ty
时,我们不止可以一次减去ty
,可以减去最大可以减去,ty > tx
处同理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: bool reachingPoints(int sx, int sy, int tx, int ty) { if(tx < sx || ty < sy) return false; while(tx > 0 && ty > 0){ if(sx == tx && sy == ty){ return true; } if(tx > ty){ tx -= max((tx - sx)/ty, 1) * ty; }else{ ty -= max((ty - sy)/tx, 1) * tx; } } return false; } };
|
这样就可以解了。