【Leetcode】780. Reaching Points

题目地址:

https://leetcode.com/problems/reaching-points/

给定一个数对 ( x , y ) (x,y) (x,y),每走一步可以到达 ( x + y , y ) (x+y,y) (x+y,y)或者 ( x , x + y ) (x,x+y) (x,x+y),再给定一个目标数对,问从初始数对出发能否走到目标数对。题目保证 x x x y y y都是正整数。

如果start和target相等,那直接返回true。否则对于某个 ( x , y ) (x,y) (x,y),一定有 x ≠ y x \ne y x=y,因为要到达 ( x , x ) (x,x) (x,x),其上一步必然是 ( 0 , x ) (0,x) (0,x)或者 ( x , 0 ) (x,0) (x,0),与 x x x是正数矛盾。而若 x > y x>y x>y,则上一步一定是 ( x − y , y ) (x-y,y) (xy,y),否则上一步一定是 ( x , y − x ) (x, y-x) (x,yx)。如此逆推回去,看看能不能推到start即可。
注意到这里可以进行一点优化。如果当 x > y x>y x>y,我们需要验证 ( x − y , y ) , ( x − 2 y , y ) . . . , ( x − k y , y ) (x-y,y),(x-2y,y)...,(x-ky,y) (xy,y),(x2y,y)...,(xky,y)(其中 x − ( k − 1 ) y > y x-(k-1)y>y x(k1)y>y x − k y < y x-ky<y xky<y)是否等于start,我们也可以这么做:求 ( t x % t y , t y ) (tx\%ty, ty) (tx%ty,ty),然后判断sy == ty(sx - tx % ty) % ty == 0,这两者的等价性非常显然。优化后的代码如下:

public class Solution {
    public boolean reachingPoints(int sx, int sy, int tx, int ty) {
        if (sx == tx && sy == ty) {
            return true;
        }
        
        while (sx <= tx && sy <= ty) {
            if (tx > ty) {
                tx %= ty;
            } else {
                ty %= tx;
            }
            
            if (sx == tx && (sy - ty) % sx == 0) {
                return true;
            }
            if (sy == ty && (sx - tx) % sy == 0) {
                return true;
            }
        }
        // 如果跳出循环了,说明sx > tx或者sy > ty,这就不可能再达到了,返回false
        return false;
    }
}

时间复杂度 O ( log ⁡ min ⁡ ( t x , t y ) ) O(\log \min(tx,ty)) O(logmin(tx,ty)),空间 O ( 1 ) O(1) O(1)

时间复杂度证明:
很显然求 ( t x , t y ) (tx,ty) (tx,ty)的最大公约数的步数可以作为时间复杂度的一个上界。先证明,如果求 a a a b b b的最大公约数的步数为 n n n,且 a > b > 0 a>b>0 a>b>0,则最小的 a a a b b b分别是 F n + 2 F_{n+2} Fn+2 F n + 1 F_{n+1} Fn+1(这里的意思是,需要步数为 n n n的所有数对里, b b b最小是 F n + 1 F_{n+1} Fn+1,然后对于这个 b b b a a a最小可以取 F n + 2 F_{n+2} Fn+2),其中 F n F_n Fn为斐波那契数, F 1 = F 2 = 1 F_1=F_2=1 F1=F2=1 F n = F n − 1 + F n − 2 F_n=F_{n-1}+F_{n-2} Fn=Fn1+Fn2。数学归纳法,如果只需要一步,此时余数为 0 0 0,所以 a = 2 = F 3 a=2=F_3 a=2=F3 b = 1 = F 2 b=1=F_2 b=1=F2,成立。假设对需要 k k k步的时候也成立,当需要 k + 1 k+1 k+1步的时候,第一步为 a = b q 0 + r 0 a=bq_0+r_0 a=bq0+r0,第二步为 b = r 0 q 1 + r 1 b=r_0q_1+r_1 b=r0q1+r1,所以 b b b最小是 F k + 2 F_{k+2} Fk+2 r 0 r_0 r0最小是 F k + 1 F_{k+1} Fk+1,而最小的 a a a q 0 = 1 q_0=1 q0=1时取到,所以 a a a最小是 F k + 3 F_{k+3} Fk+3

由上可知,而斐波那契数 F n F_n Fn n n n的关系是个对数的关系,所以时间复杂度为 O ( log ⁡ min ⁡ ( t x , t y ) ) O(\log \min(tx,ty)) O(logmin(tx,ty))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值