题目描述
解法:反向计算
题目中给定 ( 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) (tx−ty,ty)
-
如果 t x < t y tx<ty tx<ty,则上一个状态是 ( t x , t y − t x ) (tx,ty−tx) (tx,ty−tx)
因此可以从 ( 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 (ty−sy)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 (tx−sx)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)