有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?

如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升水。

你允许:

  • 装满任意一个水壶;
  • 清空任意一个水壶;
  • 从一个水壶向另外一个水壶倒水,直到装满或者倒空;

——————————————————————————
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/water-and-jug-problem
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————————————————————————
思路及算法:

首先对题目进行建模。观察题目可知,在任意一个时刻,此问题的状态可以由两个数字决定:X 壶中的水量,以及 Y 壶中的水量。

在任意一个时刻,我们可以且仅可以采取以下几种操作:

把 X 壶的水灌进 Y 壶,直至灌满或倒空,要同时修改X壶和Y壶的状态;
把 Y 壶的水灌进 X 壶,直至灌满或倒空,要同时修改X壶和Y壶的状态;
把 X 壶灌满;
把 Y 壶灌满;
把 X 壶倒空;
把 Y 壶倒空。
因此,本题可以使用深度优先搜索来解决。搜索中的每一步以 remain_x, remain_y 作为状态,即表示 X 壶和 Y 壶中的水量。在每一步搜索时,我们会依次尝试所有的操作,递归地搜索下去。这可能会导致我们陷入无止境的递归,因此我们还需要使用一个哈希结合(HashSet)存储所有已经搜索过的 remain_x, remain_y 状态,保证每个状态至多只被搜索一次。

在实际的代码编写中,由于深度优先搜索导致的递归远远超过了 Python 的默认递归层数(可以使用 sys 库更改递归层数,但不推荐这么做),因此下面的代码使用栈来模拟递归,避免了真正使用递归而导致的问题。

—————————————————————————
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/water-and-jug-problem/solution/shui-hu-wen-ti-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
—————————————————————————

class Solution:def canMeasureWater(self, x: int, y: int, z: int) -> bool:stack = [(0, 0)]self.seen = set()while stack:remain_x, remain_y = stack.pop()if remain_x == z or remain_y == z or remain_x + remain_y == z:return Trueif (remain_x, remain_y) in self.seen:continue# 以下所有状态都可能为下一个状态,所以都需要进行存储self.seen.add((remain_x, remain_y))# 把 X 壶灌满。stack.append((x, remain_y))# 把 Y 壶灌满。stack.append((remain_x, y))# 把 X 壶倒空。stack.append((0, remain_y))# 把 Y 壶倒空。stack.append((remain_x, 0))# 把 X 壶的水灌进 Y 壶,直至灌满或倒空。# 把 X 壶的水灌进 Y 壶,则X壶有两种可能状态,如果 Y 壶放不下 X 壶中的所有水,则X壶中剩下的水为remain_x - (y - remain_y)# 如果 Y 壶能存放 X 壶中的所有水,则 X 壶为空;# 如果 Y 壶被装满,则 Y 壶的状态变为remain_y + y - remain_y = y;如果 Y 壶没有被装满,则 Y 壶的状态变为 remain_y + remain_xstack.append((remain_x - min(remain_x, y - remain_y), remain_y + min(remain_x, y - remain_y)))# 把 Y 壶的水灌进 X 壶,直至灌满或倒空。stack.append((remain_x + min(remain_y, x - remain_x), remain_y - min(remain_y, x - remain_x)))return False作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/water-and-jug-problem/solution/shui-hu-wen-ti-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

复杂度分析

  • 时间复杂度:O(xy)O(xy),状态数最多有 (x+1)(y+1)(x+1)(y+1) 种,对每一种状态进行深度优先搜索的时间复杂度为 O(1)O(1),因此总时间复杂度为 O(xy)O(xy)。
  • 空间复杂度:O(xy)O(xy),由于状态数最多有 (x+1)(y+1)(x+1)(y+1) 种,哈希集合中最多会有 (x+1)(y+1)(x+1)(y+1) 项,因此空间复杂度为 O(xy)O(xy)。

—————————————————————————
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/water-and-jug-problem/solution/shui-hu-wen-ti-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
—————————————————————————

LeetCode —— 365. 水壶问题(Python3)相关推荐

  1. Leetcode.365 水壶问题

    题目链接 Leetcode.365 水壶问题 mid 题目描述 有两个水壶,容量分别为 x和 y升.水的供应是无限的.确定是否有可能使用这两个壶准确得到 z升. 如果可以得到 z升水,最后请用以上水壶 ...

  2. LeetCode 365. 水壶问题

    365. 水壶问题 题目链接-365. 水壶问题 解题思路 裴蜀定理 裴蜀等式:若a,ba,ba,b是整数,且gcd(a,b)=dgcd(a,b)=dgcd(a,b)=d,那么对于任意的整数x,yx, ...

  3. LeetCode 365. 水壶问题(最大公约数)

    文章目录 1. 题目 2. 最大公约数 1. 题目 有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的 ...

  4. LeetCode 365水壶问题(python)

    题目描述: 有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水. 你允许 ...

  5. 每日一题-leetcode 365. 水壶问题

    有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升.水的供应是无限的.确定是否有可能使用这两个壶准确得到 targetCapacity 升. 如果可以得到 target ...

  6. Leetcode 365.水壶问题

    水壶问题 有两个容量分别为 x升和 y升的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水. 你允许: 装满 ...

  7. LeetCode——365.水壶问题【贝祖定理】

    题解 AC-Code using PII = pair<int, int>;class Solution {public:bool canMeasureWater(int x, int y ...

  8. leetcode:365. 水壶问题【肥鼠定理,栈模拟dfs】

    分析:数学 显然最后的z是a和b的线性组合 也就是ax + by = z也就是说z是(a,b)的倍数 那就直接用gcd就好了 加个特判 ac code class Solution:def canMe ...

  9. [LeetCode解题报告] 365. 水壶问题

    [LeetCode解题报告] 365. 水壶问题 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 一. 题目 1. 题目描 ...

最新文章

  1. 算法之递归(3)- 链表操作
  2. could not load inserted library: /usr/lib/libgmalloc.dylib
  3. MongoDB权威指南
  4. 关于android相机开发中遇到的内存溢出的问题
  5. isight参数优化理论与实例详解_【iSight】iSIGHT Matlab简单算例
  6. 1、Tensorflow 之 saver与checkpoint
  7. Android 日夜间切换Demo
  8. 浏览器滚动条样式更改
  9. java seteditable,Java TextField.setEditable方法代碼示例
  10. sizeof运算符运算结果小汇
  11. centos7利用nexus离线搭建局域网pypi源
  12. c#参数修饰符-params
  13. [原创]商品条码管理与条码打印管理软件的实现
  14. 新华三模拟器STP和RSTP及其MSTP的作用与配置
  15. 移远EC20开发环境搭建
  16. U盘文件乱码怎么恢复正常
  17. 8b10b编码源码 matlab,8b/10b编码技术系列(一):Serdes、CDR、K码
  18. wpf修改鼠标悬停效果
  19. 大悲寺——依教奉行溯正源,良苦用心谁人知?纵然世间一比丘,不退初心证菩提。[转]
  20. L298N 驱动电机与单片机的线路连接图

热门文章

  1. 《Maintainable JavaScript》读书笔记
  2. DreamFactory入门指南 - 第1章REST和DreamFactory简介
  3. 虚拟局域网——vlan (讲解+配置)
  4. HTML连载70-相片墙、盒子阴影和文字阴影
  5. SpringMVC 控制层注解
  6. C#设计模式之9-装饰者模式
  7. 使用heroku托管服务搭建网站
  8. docker学习指南
  9. c语言指针官方解释_C语言中的指针解释了–它们并不像您想象的那么难
  10. 工作回报如何影响人的生产力_如何在减少工作的同时提高生产力