LeetCode Problems #365

2018年10月21日

#365. Water and Jug Problem

问题描述:

You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs.

If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.

Operations allowed:

  • Fill any of the jugs completely with water.
  • Empty any of the jugs.
  • Pour water from one jug into another till the other jug is completely full or the first jug itself is empty

样例:

Example 1: (From the famous "Die Hard" example)

Input: x = 3, y = 5, z = 4
Output: True

Example 2:

Input: x = 2, y = 6, z = 5
Output: False

问题分析:

本题难度为Medium!已给出的函数定义为:

class Solution:
    def canMeasureWater(self, x, y, z):
        """
        :type x: int
        :type y: int
        :type z: int
        :rtype: bool
        """

其中x、y和z都是整型变量;

 

本题为经典的水壶问题,且问题只需要判断是否能得到相应的水而不是给出具体的操作顺序,所以问题难度并不高。由于只有两个容量为x和y的水壶,若可以通过这两个水壶得到容量为z的水,则易知z=ax+by,其中a和b都是整数(这里不给出证明,但是这是容易水壶问题得出的结论)。到这里,可以循环查找对应的a和b值,但是很可能要循环很多次(例如10000*10000次),或者循环了很多次也没找到对应的a和b值,但是不能确定下一次就不是答案而停止循环,所以这种方法不是最佳。

其实可以通过x和y的最大公约数来判断,比如说g为x和y的最大公约数,则x=ng且y=mg,其中n和m都是整数,则z=ax+by=ang+bmg=(an+bm)g,即g是z的约数,所以问题的变为求x和y的最大公约数g及判断其是否为z的约数。而求最大公约数可以用辗转相除法来求。

另外,还需要考虑几种情况:

  1.  若x和y的和小于z(x+y<z),则永远无法得到z升的水,除非有一个容器可以装水(则不符合题意);
  2.  若z为0,则一定可以得到0升的水。

 

代码实现:

#coding=utf-8
class Solution:
    def canMeasureWater(self, x, y, z):
        """
        :type x: int
        :type y: int
        :type z: int
        :rtype: bool
        """
        def GCD(x,y):
            if not y: 
                return x
            else:
                return GCD(y,x%y)

        if x+y<z or (z!=0 and z%GCD(x,y)):
            return False
        else:
            return True

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值