LeetCode 780. 到达终点(数学推理/反向计算)

本文探讨了一种高效算法,利用反向计算来解决从特定坐标(sx,sy)出发到达目标坐标(tx,ty)的问题。通过辗转相除法原理,仅在tx≠ty时进行步骤调整,避免了正向计算的复杂性。适用于起点与终点坐标范围在[1,109]内的问题,时间复杂度为O(log(max(tx,ty)))。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目描述

在这里插入图片描述

在这里插入图片描述

解法:反向计算

题目中给定 ( s x , s y ) (sx,sy) (sx,sy)的范围是 [ 1 , 1 0 9 ] [1,10^9] [1,109],且每次转换,只能将另一维的数值累加到当前维,因此在转换过程中绝不会出现负数。

如果从 ( s x , s y ) (sx,sy) (sx,sy)开始正向计算,则可能的情况非常多,会超出时间限制。

( s x , s y ) (sx,sy) (sx,sy) ( t x , t y ) (tx,ty) (tx,ty)的范围都是 [ 1 , 1 0 9 ] [1,10^9] [1,109](正整数),因此对于给定的状态 ( t x , t y ) (tx,ty) (tx,ty),只有当 tx ≠ ty \textit{tx} \ne \textit{ty} tx=ty 时才存在上一个状态,且上一个状态唯一,可能的情况如下:

  • 如果 t x = t y tx=ty tx=ty,不存在上一个状态,状态 ( t x , t y ) (tx,ty) (tx,ty) 即为起点状态

  • 如果 t x > t y tx>ty tx>ty,则上一个状态是 ( t x − t y , t y ) (tx−ty,ty) (txty,ty)

  • 如果 t x < t y tx<ty tx<ty,则上一个状态是 ( t x , t y − t x ) (tx,ty−tx) (tx,tytx)

因此可以从 ( t x , t y ) (tx,ty) (tx,ty) 开始反向计算,判断是否可以到达状态 ( s x , s y ) (sx,sy) (sx,sy)

由于每一步反向操作一定是将 t x tx tx t y ty ty 中的较大的值减小,因此当 t x > t y tx>ty tx>ty 时可以直接将 t x tx tx 的值更新为 tx   m o d   ty \textit{tx} \bmod \textit{ty} txmodty,当 t x < t y tx<ty tx<ty 时可以直接将 t y ty ty 的值更新为 ty   m o d   tx \textit{ty} \bmod \textit{tx} tymodtx

更相减损法辗转相除法的进化。如果遇到一个数很大,另一个数比较小的情况,可能要进行很多次减法才能达到一次除法的效果,从而使得算法的时间复杂度退化为 O ( N ) O(N) O(N),其中 N N N是原先的两个数中较大的一个。相比之下,辗转相除法的时间复杂度稳定于 O ( l o g N ) O(logN) O(logN)

当反向操作的条件不成立时,根据 t x tx tx t y ty ty 的不同情况分别判断是否可以从起点转换到终点。

  • 如果 t x = s x tx=sx tx=sx t y = s y ty=sy ty=sy,则已经到达起点状态,因此可以从起点转换到终点。

  • 如果 t x = s x tx=sx tx=sx ty ≠ sy \textit{ty} \ne \textit{sy} ty=sy,则 t x tx tx 不能继续减小,只能减小 t y ty ty,因此只有当 t y > s y ty>sy ty>sy ( ty − sy )   m o d   tx = 0 (\textit{ty} - \textit{sy}) \bmod \textit{tx} = 0 (tysy)modtx=0 时可以从起点转换到终点。

  • 如果 t y = s y ty=sy ty=sy tx ≠ sx \textit{tx} \ne \textit{sx} tx=sx,则 t y ty ty 不能继续减小,只能减小 t x tx tx,因此只有当 t x > s x tx>sx tx>sx ( tx − sx )   m o d   ty = 0 (\textit{tx} - \textit{sx}) \bmod \textit{ty} = 0 (txsx)modty=0 时可以从起点转换到终点。

  • 如果 tx ≠ sx \textit{tx} \ne \textit{sx} tx=sx ty ≠ sy \textit{ty} \ne \textit{sy} ty=sy,则不可以从起点转换到终点。

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;
        }
    }
}
  • 时间复杂度: O ( log ⁡ max ⁡ ( tx , ty ) ) O(\log \max(\textit{tx}, \textit{ty})) O(logmax(tx,ty))。反向计算的过程与辗转相除法相似,时间复杂度是 O ( log ⁡ max ⁡ ( tx , ty ) ) O(\log \max(\textit{tx}, \textit{ty})) O(logmax(tx,ty))

  • 空间复杂度: O ( 1 ) O(1) O(1)

Reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xylitolz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值