Leetcode - 365. 水壶问题 / 倒水问题 / 栈模拟递归 / gcd


思路:

  1. 第一想法肯定是用DFS模拟倒水操作,因为每个杯子最多就三次操作,然后记录一下每次的状态,但是会超过循环的次数,所以改用栈来模拟循环。
  2. 官方题解的数学方法,即如果z是x和y公约数的倍数那么本次操作一定能完成(官方在题解里面推导了,原理没看懂,数学蒟蒻,先记下来好了)
"""
栈模拟递归
"""
class Solution:
    def canMeasureWater(self, x: int, y: int, z: int) -> bool:
        if x == z or y == z or x + y == z:
            return True
        if x + y < z:
            return False
        vis = set()
        stack = [(x, y)]
        while stack:
            tx, ty = stack.pop()
            if (tx, ty) in vis:
                continue
            # 记录搜索过的状态
            vis.add((tx, ty))
            if tx == z or ty == z or tx + ty == z:
                return True
            # x清空,x倒满,x给y倒水
            stack.append((0, ty))
            stack.append((x, ty))
            stack.append((max(0, tx - ty), min(y, ty + tx)))
            # y清空,y倒满,y给x倒水
            stack.append((tx, 0))
            stack.append((tx, y))
            stack.append((min(x, ty + tx), max(0, ty-tx)))
        return False

"""
对于数学方法而言,题目已经转换为了求最大公约数了。
"""
class Solution:
    def canMeasureWater(self, x: int, y: int, z: int) -> bool:
        if x == z or y == z or x + y == z:
            return True
        if x + y < z:
            return False
        def gcd(x, y):
            if x % y == 0:
                return y
            return gcd(y, x % y)
        return True if not z % gcd(x, y) else False
posted @ 2020-03-21 16:18  但是我拒绝  阅读(514)  评论(0编辑  收藏  举报