水壶问题
题目:有两个容量分别为x升和y升的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而得到恰好z升的水?
如果可以,最后请用以上水壶中的一个或两个盛放取得的z升水。
你允许:
- 装满任意一个水壶
- 清空任意一个水壶
- 从一个水壶向另外一个水壶倒水,直到装满或者倒空
深度优先搜索肯定是可以做的,主要是还要考虑是否出现重复状态,要考虑挺多;于是想找一种稳定的求解办法。
思路:
1.首先是想到当z大于x,y中较大的一个时,那么一定有一个壶是满的,然后加上另一个壶可能盛的水;即只需判断其中一个壶的所有可能。
2.这就引导我将两个壶分开看,**单独看一个壶**
整个问题可以看作:lis为所有可能情况
1.初始状态,a表示容量小的壶的水量,b表示容量大的壶的水量;(初始a=0,b=0)
2.将容量较小的壶不断往另一个壶装水,记录此时b中水的容量进lis;当第二个壶满了以后:
3.将此时壶1剩的水(t)加上壶2满的水加入lis,将壶1剩的水给壶2;(此时a=0,b=t)回到步骤2.
4.当t的值第二次出现时,结束循环。(壶1剩的水的值是唯一的,当第二次出现时代表已经完成一遍完整的循环)
class Solution(object):
def canMeasureWater(self, x, y, z):
"""
:type x: int
:type y: int
:type z: int
:rtype: bool
"""
lis = [0, x, y, x+y]
lis = set(lis)
if z in lis:
return True
if z > x+y or x == 0 or z == 0:
return False
#调整x代表容量小的壶
if x > y:
x, y = y, x
#temp代表x壶中可能出现的值,初始为0或者x(满状态)
temp = [0,x]
temp = set(temp)
a, b = 0,0
while True:
#t来判断跳出条件,中间记录可得到的数
#当y壶不满时,一直加满x壶的水直到溢出;
while b <= y:
b += x
lis.add(b)
if b == z:
return True
#t为x壶盛满y壶剩余的水
t = b % y
if t not in temp:
if t == z:
return True
temp.add(t)
lis.add(t)
else:
break
#将y壶的初始值改为t,返回步骤2
b = t
return False