LeetCode-365、水壶问题-中等

LeetCode-365、水壶问题-中等

有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?

如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。

你允许:

装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空

示例 1:(From the famous "Die Hard" example)

输入: x = 3, y = 5, z = 4
输出: True

示例 2:

输入: x = 2, y = 6, z = 5
输出: False

代码:

class Solution:
    def canMeasureWater(self, x: int, y: int, z: int) -> bool:
        if x+y < z:
            return False
        elif z == 0:
            return True
        elif x == 0:
            return y == z
        elif y == 0:
            return x == z
        else:
            return z%math.gcd(x, y) == 0

# 贝祖定理:若a,b是整数,且gcd(a,b)=d(a,b的最大公约数为d),那么对于任意的整数x,y,z=ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。
# 重要推论:a,b互质的充要条件是存在整数x,y使得ax+by=1。

# 题目改为:给定x,y,找到整数a,b,使得ax+by=z(z<=x+y)。ax+by=z有解的条件是,z是x,y的最大公约数的倍数,则找到x,y的最大公约数并判断z是否是其倍数就可以了。其中,a,b分别表示x,y操作的次数。

class Solution:
    def canMeasureWater(self, x: int, y: int, z: int) -> bool:
        if x+y < z:
            return False
        if z == 0:
            return True
        stack = [(0, 0)]
        tmp = set()
        while stack:
            a, b = stack.pop(0)
            if a == z or b == z or a+b == z:
                return True
            if (a, b) in tmp:
                continue
            tmp.add((a, b))
            stack.append((x, b))
            stack.append((a, y))
            stack.append((0, b))
            stack.append((a, 0))
            stack.append((0, b+a)) if a <= y-b else stack.append((a+b-y, y))
            stack.append((a+b, 0)) if b <= x-a else stack.append((x, b+a-x))
        return False
# DFS:一共只有6种操作
# 倒满x
# 倒满y
# 倒空x
# 倒空y
# x倒入y中(x倒空y不一定满或者x不一定倒空y满)
# y倒入x中(x不一定满y倒空或者x满y不一定倒空)

发布了209 篇原创文章 · 获赞 48 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/clover_my/article/details/105016475