js.水壶问题

链接:365. 水壶问题 - 力扣(LeetCode)

题目:

有两个水壶,容量分别为 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

思路:

假设是水壶a和水壶b,一共有以下六种情况:

  • 装满任意一个水壶(a装满,b装满)
  • 清空任意一个水壶(a清空,b清空)
  • 将水从一个水壶倒入另一个水壶(a倒入b,b倒入a)

第三种需要考虑原水壶的水空了和倒入水的水壶满了的情况,所以需要判断一下每次需要倒的水量。

初始的a和b为0,0,0先入栈,然后每次取出栈中的第一个元素并让它出栈,分析它的这六种情况,将可行的情况入栈。

并记录每次出栈的元素,就是已经出现过的水壶状态,将状态记入set中。

如果栈中第一个元素为在set集合中存在的元素,则出栈,continue,继续下一次寻找。

函数结束的条件是a==target||b==target||a+b==target,就是这两个壶准确得到 target 升结束。

如果栈为空了,还是没有满足函数结束条件,循环结束后返回false。

这里面有一个注意点,就是如果set集合中放的是0,0这种的数组,那么set.has比较的是数组的原地址,而不是数组中的值。所以在这里set.add(''+a,b),我在集合中存放的是字符串,这样就可以用set.has进行比较了。

代码:

/**

* @param {number} x

* @param {number} y

* @param {number} target

* @return {boolean}

*/

var canMeasureWater = function(x, y, target) {

let stack = \[0,0]

let set = new Set()

while(stack.length>0){

// 出栈,取出a和b的值

let a,b = stack.shift()

// 循环结束条件

if(a==target||b==target||a+b==target) return true

// 已经出现过的水壶状态,进入下次循环

if(set.has(''+a,b)) continue

//以下为分析中的六种情况

if(a<x) stack.push(x,b)

if(b<y) stack.push(a,y)

if(a!=0) {

stack.push(0,b)

if(b!=y) {

let diff = a+b<y?a:y-b

stack.push(a-diff,b+diff)

}

}

if(b!=0) {

stack.push(a,0)

if(a!=x) {

let diff = a+b<x?b:x-a

stack.push(a+diff,b-diff)

}

}

// 将这次的a,b加入set

set.add(''+a,b)

}

return false

};

相关推荐
夏幻灵2 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记3 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
程序猿编码3 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
三天不学习3 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194054 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
bkspiderx4 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆4 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光4 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
信奥卷王5 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵5 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表