算法题之水壶问题
水壶问题
有两个水壶,容量分别为 x 和 y 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 target 升。
你可以:
- 装满任意一个水壶
- 清空任意一个水壶
- 将水从一个水壶倒入另一个水壶,直到接水壶已满,或倒水壶已空。
示例 1:
输入: x = 3,y = 5,target = 4 输出: true 解释: 按照以下步骤操作,以达到总共 4 升水: 1. 装满 5 升的水壶(0, 5)。 2. 把 5 升的水壶倒进 3 升的水壶,留下 2 升(3, 2)。 3. 倒空 3 升的水壶(0, 2)。 4. 把 2 升水从 5 升的水壶转移到 3 升的水壶(2, 0)。 5. 再次加满 5 升的水壶(2, 5)。 6. 从 5 升的水壶向 3 升的水壶倒水直到 3 升的水壶倒满。5 升的水壶里留下了 4 升水(3, 4)。 7. 倒空 3 升的水壶。现在,5 升的水壶里正好有 4 升水(0, 4)。 参考:来自著名的 "Die Hard"
示例 2:
输入: x = 2, y = 6, target = 5 输出: false
示例 3:
输入: x = 1, y = 2, target = 3 输出: true 解释:同时倒满两个水壶。现在两个水壶中水的总量等于 3。
提示:
1 <= x, y, target <= 103
解题思路
想起了当年实习面试的时候,笔试题中有一道题目就是类似的,有两个水壶,一个3升,一个5升,问怎么才能获取4升水。当时思考了一下,然后把题目做出来了;不仅做出来,还画了一个如何操作的草图。时隔多年,还能想到当时做出题目高兴的样子,现在想想还是挺有趣的。
今天咱们来尝试用代码解出来。
最容易想到的办法,就是一直尝试,装满第一个水壶,然后倒到第二个水壶里,或者从第二个水壶里倒到第一个水壶里,利用两个壶相差的容量,尝试出最后的结果。
在这道题中,提供了两个水壶,也就是说往壶里倒水或者不倒水是可以穷举出来的,假设两个壶分别为X壶、Y壶,操作上有以下这几种情况:
- 把X壶装满
- 把Y壶装满
- 把X壶倒空
- 把Y壶倒空
- 把X壶的水倒到Y壶里,直到X壶的水倒完了或者Y壶装满了
- 把Y壶的水倒到X壶里,直到Y壶的水倒完了或者X壶装满了
如果上面几种操作都不满足,那么可以继续再来一轮操作,需要注意的是,这轮操作中,需要以上轮操作中,X壶和Y壶中剩余的水量开始操作,而不是直接以满壶或者空壶来操作。
如果没有找到满足的答案的情况,什么时候停止呢?
我们其实可以发现,第一轮的操作和后面的操作中,两个壶里剩下的水量可能会有相同的情况,那么出现的相同的水量的情况,就可以不用再重复操作了。所以我们需要用一个Set集合记录已经出现的情况,并且再下一次操作之前去除。当我们把所有情况都遍历完了,仍然没有找到符合的情况,那么就可以停止了,说明是不能获取到出目标水量的。
具体代码如下:
class Solution {public boolean canMeasureWater(int x, int y, int z) {Deque<int[]> stack = new LinkedList<int[]>();stack.push(new int[]{0, 0});Set<Long> seen = new HashSet<Long>();while (!stack.isEmpty()) {if (seen.contains(hash(stack.peek()))) {stack.pop();continue;}seen.add(hash(stack.peek()));int[] state = stack.pop();int remain_x = state[0], remain_y = state[1];if (remain_x == z || remain_y == z || remain_x + remain_y == z) {return true;}// 把 X 壶灌满。stack.push(new int[]{x, remain_y});// 把 Y 壶灌满。stack.push(new int[]{remain_x, y});// 把 X 壶倒空。stack.push(new int[]{0, remain_y});// 把 Y 壶倒空。stack.push(new int[]{remain_x, 0});// 把 X 壶的水灌进 Y 壶,直至灌满或倒空。stack.push(new int[]{remain_x - Math.min(remain_x, y - remain_y), remain_y + Math.min(remain_x, y - remain_y)});// 把 Y 壶的水灌进 X 壶,直至灌满或倒空。stack.push(new int[]{remain_x + Math.min(remain_y, x - remain_x), remain_y - Math.min(remain_y, x - remain_x)});}return false;}public long hash(int[] state) {return (long) state[0] * 1000001 + state[1];}
}
复杂度分析
- 时间复杂度:
,不同的情况最多可能有
种,我们使用深度优先搜索,深度优先的复杂度是
,所以总的时间复杂度即
。
- 空间复杂度:
,我们用了一个Stack栈和Set集合,其中Set集合中最多会放置
种情况。
相关文章:
算法题之水壶问题
水壶问题 有两个水壶,容量分别为 x 和 y 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 target 升。 你可以: 装满任意一个水壶清空任意一个水壶将水从一个水壶倒入另一个水壶,直到接水壶已满,或倒水壶已空。 示…...
Java项目: 基于SpringBoot+mysql蜗牛兼职网兼职平台管理系统(含源码+数据库+答辩PPT+毕业论文)
一、项目简介 本项目是一套基于SpringBootmysql蜗牛兼职网兼职平台管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操…...
C#数组中的Rank,GetUpperBound(), GetLength()
Rank-数组的秩,一维数组的Rank1;二维数组的Rank2; GetUpperBound()--获取每一维的索引的上限, 比如int[4,5], 那么GetUpperBound(0) 3; GetUpperBound(1) 4 ; 所以 对于二维数组来说 GetUpperBound(0)1行数; G…...
Android应用开发项目式教程——序
文章目录 Android技术本书特点本书内容本书参考 Android技术 Android是重要的客户端技术,因其开源开放的特点,Android在其初期就迅速成长为智能手机的主流操作系统,近年来更进一步成为智能电视、智能车载终端等智能设备的主流操作系统&#…...
【Spring Boot 3】【Web】统一处理 HTTP 请求体
【Spring Boot 3】【Web】统一处理 HTTP 请求体 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总…...
uni-app开发微信小程序
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,它允许开发者编写一次代码,然后发布到iOS、Android、Web(包括各种小程序平台如微信小程序、支付宝小程序、百度智能小程序等)以及各种快应用平台上。对于使用uni-app开发微信小…...
Qt开发框架--完整的软件开发框架
Qt开发框架包含一整套高度直观、模块化 的C 库类,并加载可简化应用程序开发的API。Qt 可生成高可读、易维护和可重用的代码,具有较高的运行时性能,且内存占用小。最重要的是,Qt是跨平台的。 Qt工具分为这么几个类别: …...
Python爬虫-Amazon亚马逊oData参数
前言 本文是该专栏的第37篇,后面会持续分享python爬虫干货知识,记得关注。 本文以“亚马逊Amazon”为例,主要获取亚马逊商品详情页的oData参数规律。 具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整…...
Q215 数组中第K大的元素
思路 可以用排序,但是不用全有序 还有个要求是O(n) 快排改版 快排只排需要的部分 public int findKthLargest(int[] nums, int k) {return quickSort(nums, 0, nums.length-1, nums.length-k);}public static int quickSort(int[] nums, …...
Java8特性:分组、提取字段、去重、过滤、差集、交集
总结下自己使用过的特性 将对象集合根据某个字段分组 //根据id分组 Map<String, List<Bean>> newMap successCf.stream().collect(Collectors.groupingBy(b -> b.getId().trim()));获取对象集合里面的某个字段的集合 List<Bean> list new ArrayList&l…...
Maven快速上手使用指南的笔记
Maven Mini Guides Configuring for Reproducible Builds 使用Maven实现重复构建。 检查当前使用的插件的版本。 mvn artifact:check-buildplan修改pom.xml,增加如下配置,显式指定project.build.outputTimestamp的取值: <properties>…...
MySQL面试题大全和详解,含SQL例子
若有不理解,可以问一下这几个免费的AI网站 https://ai-to.cn/chathttp://m6z.cn/6arKdNhttp://m6z.cn/6b1quhhttp://m6z.cn/6wVAQGhttp://m6z.cn/63vlPw 下面是一些常见的 MySQL 面试题及其解答,包含 SQL 示例。 1. 什么是 MySQL? 答&…...
java-redis-雪崩
Redis 雪崩问题 Redis雪崩 是指在 Redis 缓存系统中,当大量缓存同时失效时,所有请求直接打到数据库,导致数据库瞬间压力激增,甚至崩溃的现象。雪崩问题通常出现在高并发的系统中,因为缓存的失效导致后端数据库承受不了…...
如何在mac上玩使命召唤手游?苹果电脑好玩的第一人称射击游戏推荐
《使命召唤4:现代战争》(Call of Duty 4: Modern Warfare)是由Infinity Ward开发并于2007年发行的第一人称射击游戏。该游戏是《使命召唤》系列的第四部作品,是一款非常受欢迎的游戏之一,《使命召唤4:现代战…...
SimHash算法详解与应用
1. 简介 在当今信息爆炸的时代,如何有效地管理和处理海量的文本数据,尤其是去除重复内容,是一项重要的任务。SimHash 是一种巧妙的哈希算法,它不仅能快速生成文本的哈希值,还能在不同文本之间生成相似的哈希值&#x…...
RasberryPi 3B树莓派基本配置
RaspberryPi 3B树莓派基本配置 文章目录 RaspberryPi 3B树莓派基本配置一、准备工作1.1 硬件准备:1.1.1 树莓派和电源适配器:1.1.2 USB转TTL模块:1.1.3 读卡器和TF卡: 1.2 软件准备:1.2.1 下载 Raspberry Pi OS&#x…...
Docker编译环境的使用(ubuntu)
目录 Ubuntu安装docker 重启docker 拉取镜像 进入docker安装软件 提交docker 添加用户到docker组 进入docker 添加build用户 停止容器 保存docker镜像 load镜像 删除容器 Ubuntu安装docker sudo apt install docker.io 国内可用的源 Welcome to nginx! (tence…...
认知杂谈53
今天分享 有人说的一段争议性的话 I I 1.自助者天助 首先呢,咱得好好琢磨琢磨“自助者天助”这句话。这话说起来好像有点高深莫测的感觉,其实啊,道理特别简单。 就是说要是你自己都不乐意努力,那老天爷也不会平白无故地来帮你…...
量子计算信息安全威胁与应对策略分析
作者简介 赖俊森 中国信息通信研究院技术与标准研究所光网络技术与应用研究部主任工程师,正高级工程师,主要研究方向为量子信息、量子通信、量子计算等。 赵文玉 中国信息通信研究院技术与标准研究所副所长,正高级工程师,主要…...
Oracle(112)如何使用RMAN恢复数据库?
使用 RMAN(Recovery Manager)恢复 Oracle 数据库是确保数据在灾难情况下能够得到恢复的关键步骤。以下是详细的指导和代码示例,展示如何使用 RMAN 进行数据库恢复。 1. 准备工作 在开始恢复之前,需要确保以下几点: …...
保姆级教程:在ArcGIS Pro插件中集成你的自定义工具箱(以‘消除重复要素’为例)
从脚本到按钮:ArcGIS Pro插件开发实战指南 在GIS日常工作中,我们常常会遇到一些重复性的数据处理任务。比如数据质检环节的"消除重复要素"操作,虽然可以通过Python脚本实现,但每次都需要打开IDE或Python窗口执行代码&am…...
Unity UGUI轻量UI框架:200行代码实现零GC界面管理
1. 为什么还要自己手写UI框架?——当UGUI原生方案开始“卡脖子”很多人看到这个标题第一反应是:“都2024年了,还手写UI框架?Asset Store里几十个成熟方案,NGUI、FairyGUI、TextMeshPro配套的UI系统一抓一大把ÿ…...
深度学习从心电信号中解码呼吸频率:原理、实现与临床价值
1. 项目概述:从心电信号中“听”到呼吸声呼吸频率,这个我们每分钟都在进行却很少被精确量化的生命体征,在临床医学中扮演着至关重要的角色。它不仅是评估呼吸系统功能的直接指标,更是反映全身代谢、循环乃至神经系统状态的“窗口”…...
数组专项(一):数组排序、去重、查找
大家好,欢迎来到《算法面试60讲(2026最新版全真题带解析)》第19篇!上一篇我们彻底吃透了字符串专项的核心难点——BF暴力匹配与KMP高效匹配算法,搞定了字符串模块面试最难的算法考点。从本节课开始,我们正式进入算法面试第一高频模块:数组专项。 在算法面试中,数组是出…...
串口通信粘包问题:成因深度解析与项目实战解决方案
在嵌入式开发、工业工控、上位机下位机交互项目中,串口(RS232/RS485)是最基础、最常用的通信方式。绝大多数开发者都遇到过这样的问题:串口接收的数据偶尔错乱、解析报错、数据拼接异常,单次接收的数据时而半包、时而多…...
SSH工具对比:新手用户和熟练运维,选型逻辑有什么不同
结论 新手用户和熟练运维在选择 SSH 工具时,关注点往往完全不同。 新手更在意的是:能不能顺利连接、界面是否直观、文件和配置是否容易找到、网站出问题时能不能快速定位。 而熟练运维更在意的是:连接效率、命令自由度、多服务器管理能力、原…...
三十岁想从零转行现实吗?带你分辨真正有前景的好工作
我是29岁那年,完成从转行裸辞副业的职业转型。 如果你把职业生涯看成是从现在开始30岁,到你退休那年,中间这么漫长的30年,那么30岁转行完全来得及…...
Python PIL 画矩形框
基础代码 from PIL import Image, ImageDraw# 打开图片 img Image.open(your_image.jpg)# 创建绘图对象 draw ImageDraw.Draw(img)# 矩形坐标 (x1, y1, x2, y2) coords (23, 21, 69, 76)# 画矩形框(红色,线宽2) draw.rectangle(coords, ou…...
基于Arduino与nRF24L01+的无线传感器平台设计与部署指南
1. 项目概述与设计思路如果你和我一样,喜欢在阳台或者小院子里种点蔬菜瓜果,那你肯定也遇到过这样的烦恼:出门几天,心里总惦记着家里的番茄苗是不是缺水了,小温室里的温度会不会太高。传统的温湿度计只能让你在现场读数…...
紧急预警:DeepSeek代码生成中未公开的3类逻辑漂移现象(附自动化检测脚本+修复模板)
更多请点击: https://intelliparadigm.com 第一章:紧急预警:DeepSeek代码生成中未公开的3类逻辑漂移现象(附自动化检测脚本修复模板) 近期在多轮生产级代码审计中发现,DeepSeek-R1(v2.5&#x…...
