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

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.dtcms.com/a/355305.html

相关文章:

  • day083-Filebeat数据采集案例与Kibana可视化应用
  • Leetcode 494. 目标和 动态规划-01背包
  • 【踩坑记录】SpringBoot 项目报 Communications link failure 的解决方法
  • 数据结构初阶:详解双链表
  • 在angular20中使用monaco-editor
  • LLM Agent工具设计规范总结
  • Python 实现归并排序:从原理到代码
  • Ansys Electronics Desktop 2025 R2 软件界面介绍
  • open webui源码分析10-四个特征之搜索
  • 系统架构师-软件工程
  • 前端响应式设计
  • 推荐系统王树森(五)重排多样性提升
  • 银河麒麟桌面操作系统:为什么不让root直接登录图形界面?以及如何安全地解决这个问题
  • 英伟达营收和利润均超出市场预期,但盘后一度跌超5%
  • Groovy语法入门
  • [光学原理与应用-321]:皮秒深紫外激光器产品不同阶段使用的工具软件、对应的输出文件
  • 客户案例 | 国际知名内衣品牌x甄知科技,领航IT服务新征程
  • linux 网络:并发服务器及IO多路复用
  • 开发避坑指南(42):Vue3 element ui el-table单选实现方案
  • HTML静态页面实现材积计算器和材积表生成器
  • 动手学深度学习(pytorch版):第七章节—现代卷积神经网络(5)批量规范化
  • 吴炳锡:AI 时代下的湖仓一体化平台建设的思考
  • 从枯燥C++到趣味音乐:我的Windows系统底层探索之旅
  • 公共字段自动填充
  • Foundry工具大全
  • uniapp vue3 canvas实现手写签名
  • 【Node.js从 0 到 1:入门实战与项目驱动】2.4 开发工具推荐(VS Code 、IDEA及插件、终端工具、调试工具)
  • Cesium入门教程(二)环境搭建(HTML版)
  • QT:【第一个QT程序】【信号和槽】
  • 使用uni-app和Canvas生成简易双列表格布局并长按下载到本地