一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
一、题目
leetcode 到达终点
给定四个整数 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
二、题解
简单的说就是需要将sx,sy的值经过一些操作后分别变为tx,ty。每次的操作中sx可以不变或者变为sx + sy,同样的sy可以不变或者变为sy + sx。最后可以变为tx,ty则为true,否则为false。
方法一
简单的来讲,我们可以模拟来枚举sx,sy每一次操作的结果,然后与tx,ty比较,但是这样操作的结果可能有很多种,同时sx, sy, tx, ty的值范围也比较大,那么执行的时间复杂度可能很高,所以我们可以想想有没有别的办法。首先每次操作值都是相加的结果,所以sx不能大于tx,sy也不能大于ty;同时我们注意到sx, sy, tx, ty的值都是大于0的正整数,那么有没有可能用tx,ty相减的操作来得到sx,sy。如果sx,sy经过n次互相加的操作可以得到tx,ty。反向操作tx,ty互相减后也必定能得到sx,sy。又因为sx,sy都是大于0的正整数,所以tx,ty相减的操作时只能用大数减小数,不然会出现负数是不符合的。所以当tx > ty时,可以将tx变为tx mod ty,而当ty > tx时就将ty变为ty mod tx。当到最后无法操作了再判断是否能得到sx,sy,如果tx等于sx,那么就直接返回操作ty为(ty - sy) % tx的结果是否等于0,如果ty等于sy,那么就直接返回操作tx为(tx - sx) % ty的结果是否等于0,否则直接返回false,什么无法得到sx,sy,也就是sx,sy无法经过旋转变为tx,ty。
三、代码
方法一 Java代码
class Solution {
public boolean reachingPoints(int sx, int sy, int tx, int ty) {
if (sx > tx || sy > ty) {
return false;
}
while (tx > sx && ty > sy) {
if (tx > ty) {
tx %= ty;
} else {
ty %= tx;
}
}
if (tx == sx) {
return (ty - sy) % tx == 0;
} else if (ty == sy) {
return (tx - sx) % ty == 0;
} else {
return false;
}
}
}
时间复杂度:O(n),可能需要n次操作计算才能得到结果。
空间复杂度:O(1),只需常数空间变量。