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

猜你喜欢

转载自blog.csdn.net/qq_38789531/article/details/83244830
365
今日推荐