0
点赞
收藏
分享

微信扫一扫

LeeCode每日一题98.到达终点

龙毓七七 2022-04-13 阅读 49
java

给定四个整数 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 <= 109

选自LeeCode评论

一点点总结思考

  • 本质上是 二叉树

为什么有反向思维,其实这就是一个 二叉树中判断 原点 是否是 目标节点的祖先节点的问题,我们如果选择从原节点 推导 目标节点,这就是一个指数时间复杂度的问题,而如果从目标节点不断求它的父节点,这就是对数时间复杂度的一个问题

对于节点(x,y)

  • 它的左子节点是(x+y,y),性质就是x坐标>y坐标

  • 它的左子节点是(x,x+y),性质就是x坐标<y坐标

对于节点(x,y),它的父节点是

  • if (x > y) -> (x-y,y)

  • if (x < y) -> (x,y-x)

因此,我们可以从目标节点向上搜索到祖先节点。

但是由于数量级较大,一次次做减法会超时,stackoverflow

因此我们可以加速这一个过程。

对于一个真正的树来说,我们可能只能通过先遍历一个使用哈希表统计每个节点的父节点,但是其实我们已经掌握了访问父节点的方法,那就是做一次减法,并且我们可以一次做好多减法,因为有乘法!

较大值直接减去n个较小值,使得数值逼近结果,是大于原坐标的最小值。

有的时候,较大值已经最逼近结果了,因此就减去一次较小值,使得小于原坐标,从而在下次递归被淘汰,算是剪枝吧。

完整代码

class Solution {

  boolean res=false;

  public boolean reachingPoints(int sx, int sy, int tx, int ty) {

​    dfs(tx,ty,sx,sy);

​    return res;

  }

  public void dfs(int v1,int v2,int target1,int target2){

​    if(res)return;

​    if(v1<target1||v2<target2) return;

​    if(v1==target1&&v2==target2) {

​      res=true;

​      return;

​    }

​    if(v1==v2) return;

​    //状态变化的快一点

​    if(v1>v2){

​      int n=(int)(((double)v1-target1)/(double)v2);

​      if(n==0) n=1;

​      if(n!=0) dfs(v1-n*v2,v2,target1,target2);

​    }else{

​      int n=(int)(((double)v2-target2)/(double)v1);

​      if(n==0) n=1;

​      dfs(v1,v2-n*v1,target1,target2);

​    }

  }

}

官方解法:

public class reachingPoints {
    class Solution {
        public boolean reachingPoints(int sx, int sy, int tx, int ty) {
            while (tx > sx && ty > sy && tx != ty) {
                if (tx > ty) {
                    tx %= ty;
                } else {
                    ty %= tx;
                }
            }
            if (tx == sx && ty == sy) {
                return true;
            } else if (tx == sx) {
                return ty > sy && (ty - sy) % tx == 0;
            } else if (ty == sy) {
                return tx > sx && (tx - sx) % ty == 0;
            } else {
                return false;
            }
        }
    }


}
举报

相关推荐

0 条评论