当前位置: 首页 > ops >正文

Swift 解法详解 LeetCode 365:水壶问题

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码拆解
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题其实就是经典的 “两个水壶问题”,你可能在电影《虎胆龙威3》里见过,布鲁斯·威利斯用两个水壶精确量出 4 升水来解除炸弹。这题就是把那个场景搬到了编程世界里。

我们的目标是:给定两个水壶的容量,看看能不能通过倒水、装满、倒空等操作,刚好得到指定的 target 升水。

描述

题目设定:

  • 有两个水壶,容量分别是 xy 升。

  • 水无限供应。

  • 操作允许:

    1. 把任意一个水壶装满
    2. 把任意一个水壶清空
    3. 把一个水壶里的水倒进另一个水壶,直到前者空或者后者满

问题:能不能正好量出 target 升?

示例 1

输入: x = 3, y = 5, target = 4
输出: true

示例 2

输入: x = 2, y = 6, target = 5
输出: false

示例 3

输入: x = 1, y = 2, target = 3
输出: true

题解答案

其实解法有两个方向:

  1. 数学解法(最大公约数 GCD)

    • 经典定理:只要 target <= x + y,并且 targetgcd(x, y) 的倍数,就能得到。
    • 这就是数论里的贝祖定理。
    • 这个方法非常简洁高效。
  2. 模拟解法(BFS/DFS 搜索所有可能的状态)

    • 模拟真实倒水过程,尝试所有可能的壶水量组合,看是否能达到 target
    • 更直观,但效率会差一些。

我这里用 Swift 先写 数学解法,然后再在分析里扩展到模拟解法。

题解代码分析

下面是 Swift 的数学解法代码:

import Foundationclass Solution {func canMeasureWater(_ x: Int, _ y: Int, _ target: Int) -> Bool {// 如果目标超过两个水壶加起来的容量,直接不可能if target > x + y {return false}// 如果刚好等于总容量,也行if target == x + y {return true}// 如果目标是 0 也 trivially 成立if target == 0 {return true}// 使用最大公约数判断return target % gcd(x, y) == 0}// 求最大公约数(辗转相除法)private func gcd(_ a: Int, _ b: Int) -> Int {if b == 0 { return a }return gcd(b, a % b)}
}// MARK: - Demo 演示
let solution = Solution()print("示例1: \(solution.canMeasureWater(3, 5, 4))") // true
print("示例2: \(solution.canMeasureWater(2, 6, 5))") // false
print("示例3: \(solution.canMeasureWater(1, 2, 3))") // true

代码拆解

  1. 判断边界情况

    • 如果 target 比两个壶加起来还大,那不可能。
    • 如果 target 等于总容量,那就直接可以倒满。
    • 如果 target = 0,也 trivially 成立。
  2. 用最大公约数 GCD 判断

    • 数学原理是:能倒出的水量一定是 gcd(x, y) 的倍数。
    • 所以只要 target % gcd(x, y) == 0,就能实现。
  3. Demo 测试
    三个示例跑完结果都正确。

示例测试及结果

运行结果:

示例1: true
示例2: false
示例3: true

再自己加几个测试:

print(solution.canMeasureWater(6, 10, 8)) // true,因为 gcd(6,10)=2,8是2的倍数
print(solution.canMeasureWater(6, 10, 7)) // false,因为 gcd=2,7不是倍数
print(solution.canMeasureWater(4, 4, 8))  // true,两个壶一起装满就行

时间复杂度

  • 主要就是求一次最大公约数,时间复杂度 O(log(min(x, y)))
  • 非常快。

空间复杂度

  • 除了递归栈,几乎没有额外空间,复杂度是 O(1)

总结

这题其实一眼看上去像 BFS/DFS 的模拟搜索题,但背后藏着一个非常优雅的数学结论。
核心公式就是:target % gcd(x, y) == 0target <= x + y

在实际生活中,这种场景也经常遇到,比如:

  • 你有两个量杯,要量出指定的水。
  • 工厂配料时,用不同规格的容器去配比原料。
  • 甚至调酒的时候,也能用这个方法。

如果你喜欢更直观的解法,也可以用 BFS 来写,把 (a, b) 表示当前两个壶的状态,然后不断倒水直到找到目标。这个解法更贴近真实操作,但效率会差一些。

http://www.xdnf.cn/news/18945.html

相关文章:

  • Java -- 文件基础知识--Java IO流原理--FileReader
  • 了解ADS中信号和电源完整性的S参数因果关系
  • hintcon2025 Verilog OJ
  • 【python】python进阶——生成器
  • 数据结构01:顺序表
  • 次元小镇官网入口 - 二次元动漫社区|COS绘画插画壁纸分享
  • [数据结构] ArrayList与顺序表(下)
  • STM32——PWR
  • 机器视觉学习-day06-图像旋转
  • KafKa学习笔记
  • 【Day 35】Linux-Mysql错误总结
  • DA14531(Cortex-M0+)之Wake-up Interrupt Controller (WIC)
  • React学习教程,从入门到精通, ReactJS - 安装:初学者指南(3)
  • linux 网络:并发服务器及IO多路复用
  • 如何将yolo训练图像数据库的某个分类的图像取出来
  • element-plus的el-scrollbar显示横向滚动条
  • 使用华为 USG6000防火墙配置安全策略
  • 传输层协议介绍
  • 企业通讯软件以安全为基,搭建高效的通讯办公平台
  • Python篇---返回类型
  • 【论文阅读】PEPNet
  • amis上传组件导入文件接口参数为base64格式的使用示例
  • 计算机三级嵌入式填空题——真题库(22)原题附答案速记
  • 强化学习与注意力机制的AlignSAM框架解析
  • 微算法科技(NASDAQ:MLGO)推出创新型混合区块链共识算法,助力物联网多接入边缘计算
  • [n8n] 工作流数据库管理SQLite | 数据访问层-REST API服务
  • Paimon——官网阅读:Flink 引擎
  • 前端javascript在线生成excel,word模板-通用场景(免费)
  • AbMole小课堂丨详解野百合碱在动物肺动脉高压、急性肺损伤、静脉闭塞肝病造模中的原理及应用
  • Go 语言常用命令使用与总结