题目

给定四个整数 sx , sy ,tx 和 ty,如果通过一系列的转换可以从起点 (sx, sy) 到达终点 (tx, ty),则返回 true,否则返回 false。

从点 (x, y) 可以转换到 (x, x+y) 或者 (x+y, y)。

示例 1:

输入: sx = 1, sy = 1, tx = 3, ty = 5
输出: true
解释:
可以通过以下一系列转换从起点转换到终点:
(1, 1) -> (1, 2)
(1, 2) -> (3, 2)
(3, 2) -> (3, 5)

示例 2:

输入: sx = 1, sy = 1, tx = 2, ty = 2
输出: false
示例 3:

输入: sx = 1, sy = 1, tx = 1, ty = 1
输出: true

提示:

1 <= sx, sy, tx, ty <= 10^9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reaching-points
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

数据范围太大,如果从780. 到达终点 - 图1780. 到达终点 - 图2正向搜索,一定会超时或者内存溢出,需要转变思路。

如果从780. 到达终点 - 图3780. 到达终点 - 图4开始考虑,可以发现,按照题目规则只能减小780. 到达终点 - 图5780. 到达终点 - 图6中较大的值,如果减小较小的那个,需要减去比自己大的数就变为负数了,显然不可行。

因此,不断减小780. 到达终点 - 图7780. 到达终点 - 图8,每次将较大的值减小。如果一次只减小一步,会发现还是超时,因此需要加速这个过程。例如,输入780. 到达终点 - 图9780. 到达终点 - 图10大于780. 到达终点 - 图11,不是将780. 到达终点 - 图12每个循环减780. 到达终点 - 图13,而是一次循环中尽可能减去更多的780. 到达终点 - 图14,最多可以减去780. 到达终点 - 图15%2Fty%3D(100-10)%2F5#card=math&code=%28tx-sx%29%2Fty%3D%28100-10%29%2F5&id=GbQJ7)个780. 到达终点 - 图16,这样就加快了。

代码

  1. class Solution {
  2. public boolean reachingPoints(int sx, int sy, int tx, int ty) {
  3. while (tx >= sx && ty >= sy) {
  4. if (sx == tx && sy == ty) {
  5. return true;
  6. }
  7. if (tx > ty) {
  8. // 使用max是因为tx最少要减去1个ty,下面同理
  9. tx -= Math.max((tx - sx) / ty, 1) * ty;
  10. } else {
  11. ty -= Math.max((ty - sy) / tx, 1) * tx;
  12. }
  13. }
  14. return false;
  15. }
  16. }