LeetCode 780到达终点

423 阅读2分钟
/**
 * @param {number} sx
 * @param {number} sy
 * @param {number} tx
 * @param {number} ty
 * @return {boolean}
 * 
 * 算法: 将(tx, ty)不断变小, 直到(tx, ty)与(sx, sy)相等。
根据规则, (tx, ty)只能由一个数对变来, 不可能由两个数对变来。
当tx > ty时, (tx, ty)的最近一个比他小的数对是(tx - ty, ty),
当tx < ty时, (tx, ty)的最近一个比他小的数对是(tx, ty - tx),
当tx == ty时, 只能与(sx, sy)比较是否相等。相等就是true, 不能结果就是false
 */
var reachingPoints = function(sx, sy, tx, ty) {
    /*
    如果tx < sx 或ty < sy, 可以直接返回false, 不进while循环
    */
    while((tx >= sx) && (ty >= sy)) {
        /* 拦截相等, 这里包括了(tx === sx) && (ty === sy)的情况和(tx > sx) && (ty > sy) && (tx === ty)的情况 */
        if(tx === ty) break
        /**
         * 剩下的情况有三种:
         * 1. ty === sy
         * 2. tx === sx
         * 3. (ty > sy) && (tx > sx) 
         * 对第1中情况, tx必须能通过减0个或n个ty变成sx, 否则无论如何都无法将终点数对变成起点数对
         *第二种情况类似
         对第3种情况,可分两种情况:
         (1) tx > ty
         (2) ty > tx
         如果是情况(1), 那么必须将tx - ty   n次, 直到tx <= ty(tx === ty的话直接退出while),
         因为这时候ty !== sy, 如果tx 减 (n - k)个ty使得tx > sx,那么要使(tx, ty)与(sx, sy)相等,那么下次还是要tx - ty,直到tx === sx,或tx <= ty。如果tx减(n - k2)(其中k2 < k),个ty后tx === sx,
         那么进入了情况2, 那这时候必须(ty === sy)或 ((ty - sy %) tx === 0),在情况(1)中ty !== sy, 且(ty > sy) && (ty < tx) 也就是说, ((ty - sy) % tx === 0)为false。这种情况下, 不管tx是一直减ty直到 tx <ty还是减一半, 结果是一样的, 都是false。如果tx减(n - k2)(其中k2 < k),个ty后tx > sx 且tx减(n - k2 + 1)====(其中k2 < k),个ty后tx < sx,这个时候如果减到tx > sx为止, 因为ty > sy,那么下一次还是必须tx - ty,就只能继续减到一次直到tx < sx,这种情况下最终结果就是false,不管是减一部分还是减n个ty。如果tx 减 n个ty后 tx === sx,这时因为ty > tx 且ty > sy,那就根据等式(ty - sy) % tx === 0判断。如果tx减 n个 ty后 tx > sx,那有就进入了情况(2),情况(2)的判断与情况(1)类似。也就是说, 对于情况3, tx 减满n个ty后必须有 tx >= sx才有可能为true, 否则一定为false 

         */
        if(ty === sy) {
            return (tx - sx) % ty === 0
        } else if(tx === sx) {
            return (ty - sy) % tx === 0
        }else if(ty > tx) {
            // 可以一减到底, 因为如果一减到底后 tx < sx,那结果一定是false,
            // 如果减后tx >= sx,那就进入了新的循环
            ty %= tx
        } else tx %= ty
    }
    return (tx === sx) && (ty === sy)
};```