Water and Jug Problem
2016-09-07 19:57
232 查看
题目描述如下
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:
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
我记得之前手机里面有个游戏是这样的,所以一下子理解了题目(题目里面说的是测得z得容积,我觉得可以理解成你往z中倒多少的水能到满),就是通过把杯子x, y, z里的水倒来倒去,最后把z给倒满,有三个要求是
每次接水必须接满
每次倒水必须倒空
将水从一个杯子x倒向另一个杯子y时,除非x空了而或者y满了才能停止。
比如例子 1有两种方法
x接满倒入y中,再接满倒入y中,y满的时候x剩1,将x剩余倒入z中,x接满再倒入中,z正好接满
x接满倒入y中,在接满倒入y中,x水倒掉,y倒入x中,y中剩余2,倒入z;重复以上步骤
因此首先想到的是,有x, y两个罐子我们相当于可以得到
[x, y, y%x, x - y%x]这四个数来组成z,但是.想不到一个好的方法去解决这个问题,四个数的话感觉复杂度好高,这个问题留在这,看书的过程中留个心。
于是换个思维,实际上,所得到的新数是通过
new = m*x + n*y的到的,倒入为+倒出为负,第一个例子的步骤就可以理解为3+3-5+3,即 3*3-5,于是问题就变成了了求解是否存在m,n满足这个等式.
由裴蜀定理(描述的比较通俗)裴蜀定理
对任何整数x、y和它们的最大公约数d,关于未知数m和n的线性丢番图方程(称为裴蜀等式):m∗x+n∗y=z
有整数解时当且仅当z是d的倍数。
现在问题就演变成了求数x与y的最大公约数resid,看它是否能被z整除。
求最大公约数的主要方法有两种:
辗转相除法(欧几里得)核心理论就是:
gcd(x,y)=gcd(y,r)其中r=x mod y
设d=gcd(x,y), x=ky+r−>md=knd+r因此 r=(m−kn)d能被x,y的最大公约数d整除,现需要证明,n 与 m-kn 互质,即可证明y 与 r最大公约数为d。若n 与 m-kn 有某个公约数 l则y 与 r的最大公约数为d*l,与假设不负(没有很严谨的证明哈,只是理解)。
根据此式可以用递归的方法来实现求得公约数,而递归的终止条件就是x mod y=0
当x mod y=0说明x能被y整除,y=gcd(x,y),程序如下
但是,提交后测试数据中有 0, 0 , 0,再加上限制条件x+y>=z,给你的总容量只有x+y你是没有办法称出大于这个值得水,修改后代码如下,速率beat 99.3%
尴尬….今天才看到原来是leetcode的编译器更新了,所以现在体检的方法总会比之前提交的快很多….所以,这个图没有任何参考性啦
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
我记得之前手机里面有个游戏是这样的,所以一下子理解了题目(题目里面说的是测得z得容积,我觉得可以理解成你往z中倒多少的水能到满),就是通过把杯子x, y, z里的水倒来倒去,最后把z给倒满,有三个要求是
每次接水必须接满
每次倒水必须倒空
将水从一个杯子x倒向另一个杯子y时,除非x空了而或者y满了才能停止。
比如例子 1有两种方法
x接满倒入y中,再接满倒入y中,y满的时候x剩1,将x剩余倒入z中,x接满再倒入中,z正好接满
x接满倒入y中,在接满倒入y中,x水倒掉,y倒入x中,y中剩余2,倒入z;重复以上步骤
因此首先想到的是,有x, y两个罐子我们相当于可以得到
[x, y, y%x, x - y%x]这四个数来组成z,但是.想不到一个好的方法去解决这个问题,四个数的话感觉复杂度好高,这个问题留在这,看书的过程中留个心。
于是换个思维,实际上,所得到的新数是通过
new = m*x + n*y的到的,倒入为+倒出为负,第一个例子的步骤就可以理解为3+3-5+3,即 3*3-5,于是问题就变成了了求解是否存在m,n满足这个等式.
由裴蜀定理(描述的比较通俗)裴蜀定理
对任何整数x、y和它们的最大公约数d,关于未知数m和n的线性丢番图方程(称为裴蜀等式):m∗x+n∗y=z
有整数解时当且仅当z是d的倍数。
现在问题就演变成了求数x与y的最大公约数resid,看它是否能被z整除。
求最大公约数的主要方法有两种:
辗转相除法(欧几里得)核心理论就是:
gcd(x,y)=gcd(y,r)其中r=x mod y
设d=gcd(x,y), x=ky+r−>md=knd+r因此 r=(m−kn)d能被x,y的最大公约数d整除,现需要证明,n 与 m-kn 互质,即可证明y 与 r最大公约数为d。若n 与 m-kn 有某个公约数 l则y 与 r的最大公约数为d*l,与假设不负(没有很严谨的证明哈,只是理解)。
根据此式可以用递归的方法来实现求得公约数,而递归的终止条件就是x mod y=0
当x mod y=0说明x能被y整除,y=gcd(x,y),程序如下
class Solution(object): def canMeasureWater(self, x, y, z): dmax = max(x, y) dmin = min(x, y) resid = self.gcd(dmax, dmin) return True if z % resid == 0 else False def gcd(self, x, y): return x if b658 y == 0 else self.gcd(y, x%y)
但是,提交后测试数据中有 0, 0 , 0,再加上限制条件x+y>=z,给你的总容量只有x+y你是没有办法称出大于这个值得水,修改后代码如下,速率beat 99.3%
class Solution(object): def canMeasureWater(self, x, y, z): dmax = max(x, y) dmin = min(x, y) if dmin ==0 and dmax ==z or z ==0: return True elif dmin == 0 and dmax != z or x+y<z: return False resid = self.gcd(dmax, dmin) return True if z % resid == 0 else False def gcd(self, x, y): return x if y == 0 else self.gcd(y, x%y)
尴尬….今天才看到原来是leetcode的编译器更新了,所以现在体检的方法总会比之前提交的快很多….所以,这个图没有任何参考性啦
相关文章推荐
- Java中使用辗转相除法求最大公约数
- 使用Python求解最大公约数的实现方法
- Python实现求最大公约数及判断素数的方法
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解