题目描述

解题思路

思路一:裴蜀定理-数学法

  1. 由题意,每次操作只会让桶里的水总量增加x或y,或者减少x或y,即会给水的总量带来x或y的变化量,转为数字描述即为:找到一对整数a,b使得下式成立:
  1. ax+by=z
  1. 分析知,要完成操作,需要满足:
  1. z<=x+y(a,b存在)
  1. 由裴蜀定理:
  1. zx,y的最大公约数的倍数=>ax+by=z有解
  1. // C++
  2. class Solution {
  3. public:
  4. bool canMeasureWater(int x, int y, int z) {
  5. if(x + y < z)
  6. return false;
  7. if(x == 0 || y == 0)
  8. return (z == 0 || x + y == z);
  9. return (z % gcd(x, y) == 0);
  10. }
  11. };
  12. // T(n) = O(log(min(x,y)),即计算最大公约数所使用的辗转相除法
  13. // S(n) = O(1)

思路二:DFS

  1. 对题目进行建模,分析可知,在任意一个时刻,问题的状态有两个数字决定:X壶中的水量,以及Y壶中的水量;
  2. 可以采取以下操作:
    • 把X壶的水灌进Y壶,直至灌满或者倒空;
    • 把Y壶的水灌进Y壶,直至灌满或者倒空;
    • 把X壶灌满;
    • 把Y壶灌满;
    • 把X壶倒空;
    • 把Y壶倒空;
  3. 搜索中的每一步以 remain_x, remain_y 作为状态,即表示 X 壶和 Y 壶中的水量。在每一步搜索时,我们会依次尝试所有的操作,递归地搜索下去。但要保证每个状态至多只被搜索一次。
  1. # Python
  2. class Solution:
  3. def canMeasureWater(self, x: int, y: int, z: int) -> bool:
  4. stack = [(0, 0)]
  5. self.seen = set()
  6. while stack:
  7. remain_x, remain_y = stack.pop()
  8. if remain_x == z or remain_y == z or remain_x + remain_y == z:
  9. return True
  10. if (remain_x, remain_y) in self.seen:
  11. continue
  12. self.seen.add((remain_x, remain_y))
  13. # 把 X 壶灌满。
  14. stack.append((x, remain_y))
  15. # 把 Y 壶灌满。
  16. stack.append((remain_x, y))
  17. # 把 X 壶倒空。
  18. stack.append((0, remain_y))
  19. # 把 Y 壶倒空。
  20. stack.append((remain_x, 0))
  21. # 把 X 壶的水灌进 Y 壶,直至灌满或倒空。
  22. stack.append((remain_x - min(remain_x, y - remain_y), remain_y + min(remain_x, y - remain_y)))
  23. # 把 Y 壶的水灌进 X 壶,直至灌满或倒空。
  24. stack.append((remain_x + min(remain_y, x - remain_x), remain_y - min(remain_y, x - remain_x)))
  25. return False
  26. # T(n) = O(xy),状态数最多有(x+1)(y+1)种,每一种状态进行DFS为O(1)
  27. # S(n) = O(xy),set存入状态数

总结

  • DSA相关:相关数据结构为栈,哈希表,相关的算法为数学
  • 语言相关:由于深度优先搜索导致的递归远远超过了 Python 的默认递归层数,使用栈来模拟递归,避免了真正使用递归而导致的问题。
  • 其他:数学结论也很重要啊!

【LeetCode】365.水壶问题的更多相关文章

  1. Java实现 LeetCode 365 水壶问题

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

  2. Leetcode 365.水壶问题

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

  3. Leetcode 365. Water and Jug Problem

    可以想象有一个无限大的水罐,如果我们有两个杯子x和y,那么原来的问题等价于是否可以通过往里面注入或倒出水从而剩下z. z =? m*x + n*y 如果等式成立,那么z%gcd(x,y) == 0. ...

  4. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  5. C#LeetCode刷题-数学

    数学篇 # 题名 刷题 通过率 难度 2 两数相加   29.0% 中等 7 反转整数 C#LeetCode刷题之#7-反转整数(Reverse Integer) 28.6% 简单 8 字符串转整数 ...

  6. LeetCode刷题总结-数学篇

    本文总结LeetCode上有数学类的算法题,推荐刷题总数为40道.具体考点分析如下图: 1.基本运算问题 题号:29. 两数相除,难度中等 题号:166. 分数到小数,难度中等 题号:372. 超级次 ...

  7. 【LeetCode】2020-03 每日一题

    121. 买卖股票的最佳时机(简单) [分类]:模拟.思维 [题解]:可以用O(n)的复杂度完成,只需要在遍历的时候记录到当前位置为止买入股票的最小价格minn,再维护一个当前卖出股票价(a-minn ...

  8. leedcode算法解题思路

    1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  9. LeetCode 461 汉明距离/LintCode 365 统计二进制中1的个数

    LeetCode 461. 汉明距离 or LintCode 365. 二进制中有多少个1 题目一:LeetCode 461. 汉明距离 LeetCode 461.明距离(Hamming Distan ...

随机推荐

  1. 题解 CF611H 【New Year and Forgotten Tree】

    Solution 提供一种新思路. 首先考虑如何判断一个状态是否合法. 考虑把所有十进制长度一样的数缩成一个点. 这样的点的个数 \(\le 5\). 蒟蒻猜了一个结论:只要满足对于所有缩出来的点的子 ...

  2. JavaSE19-IO特殊流和Properties集合

    1.IO特殊操作流 1.1 标准输入流 System类中有两个静态的成员变量 public static final InputStream in:标准输入流.通常该流对应于键盘输入或由主机环境或用户 ...

  3. element Cascader 多选 点击文字选中

    html 部分 1 <el-form-item label="A部署位置" > 2 <el-cascader 3 v-model="itemType.a ...

  4. 关于MySQL索引知识与小妙招 — get get get

    一.索引基本知识 1.1 索引的优点 大大减少了服务器需要扫描的数据量,加快数据库的检索速度 帮助服务器避免排序和临时表 将随机io变成顺序io 1.2 索引的用处 速查找匹配WHERE子句的行 从c ...

  5. 基于XGBoost模型的幸福度预测——阿里天池学习赛

    加载数据 加载的是完整版的数据 happiness_train_complete.csv . import numpy as np import pandas as pd import matplot ...

  6. hugging face-基于pytorch-bert的中文文本分类

    1.安装hugging face的transformers pip install transformers 2.下载相关文件 字表: wget http://52.216.242.246/model ...

  7. [leetcode]61. Rotate List反转链表k个节点

    类似于找链表的后k个节点 不同的是要把前边的接到后边 public ListNode rotateRight(ListNode head, int k) { //特殊情况 if (head==null ...

  8. RTC_Configuration

    Void RTC_Configuration(void)// 实时时钟的初始化配置 { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Peri ...

  9. [linux]makefile多目录

    在使用makefile多目录编写前需要掌握几个函数及符号 自定义变量 target=edit 引用的时候直接使用 $(target) 有点像C语言中的#define,这里的 $(target)会被替换 ...

  10. 有关CSS 定位中的盒装模型、position、z-index的学习心得

    开始整体之前我需要说明两个概念: 第一个就是   一切皆为框  也就是说在HTML中的不管是是块级的还是内联的,都可以认为成块的,唯一的区别就是块的会独自占据一行 第二个文档流:  一个网页可以看作是 ...