Leetcode 365 水壶问题 BFS

 

  最优解法为借助贝祖定理计算最大公约数,但本次只拿出 BFS 解法。个人觉着虽然效率低下,但BFS 解法更接近计算机思维,我们告诉计算机如何去做,其余的由来计算机完成。更符合刷题的初衷。

  JAVA:

private final boolean canMeasureWaterBFS(int x, int y, int z) {
        if (x + y < z) {
            return false;
        }
        Queue<Long> queue = new LinkedBlockingQueue<>();
        Set<Long> set = new HashSet<Long>();
        queue.add((long) 0);
        while (!queue.isEmpty()) {
            long currLon = queue.poll();
            if (set.contains(currLon)) continue;
            set.add(currLon);
            int currX = (int) (currLon >> 32);
            int currY = (int) currLon;
            if (currX == z || currY == z || currX + currY == z) {
                return true;
            }
            if (currX != 0) queue.add((long) currY);
            if (currY != 0) queue.add(((long) currX) << 32);
            if (currX != x) queue.add(combin(x, currY));
            if (currY != y) queue.add(combin(currX, y));
            if (currY < y && currX > 0) {
                if (currX > y - currY) queue.add(combin(currX - y + currY, y));
                else queue.add(combin(0, currY + currX));
            }
            if (currX < x && currY > 0) {
                if (currY > x - currX) queue.add(combin(x, currY - x + currX));
                else queue.add(combin(currX + currY, 0));
            }
        }
        return false;
    }

    private long combin(int x, int y) {
        long xLong = (long) x;
        xLong = xLong << 32;
        return xLong | y;
    }

  JS:

var canMeasureWater = function (x, y, z) {
    let source = [[0, 0]];
    let set = new Set();
    while (source.length) {
        let currLen = source.length;
        let stack = [];
        while (currLen--) {
            let curr = source.shift();
            if (set.has(curr+ '')) continue;
            set.add(curr+ '');
            let currX = curr[0];
            let currY = curr[1];
            if (currX == z || currY == z || currX + currY == z) return true;
            if (currX == 0) stack.push([x, currY]);
            if (currY == 0) stack.push([currX, y]);
            if (currX == x) stack.push([0, currY]);
            if (currY == y) stack.push([currX, 0]);
            if (currX >= y - currY) stack.push([currX - y + currY, y]);
            if (currY >= x - currX) stack.push([x, currY - x + currX]);
            if (currX > 0 && currX < y - currY) stack.push([0, currX + currY]);
            if (currY > 0 && currY < x - currX) stack.push([currX + currY, 0]);
        }
        source = stack.slice(0);
    }
    return false;
};
原文地址:https://www.cnblogs.com/niuyourou/p/13709462.html