365. Water and Jug Problem

365. Water and Jug Problem
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs.

If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.

Operations allowed:

Fill any of the jugs completely with water.
Empty any of the jugs.
Pour water from one jug into another till the other jug is completely full or the first jug itself is empty.

Example 1:
Input: x = 3, y = 5, z = 4
Output: True

Example 2:
Input: x = 2, y = 6, z = 5
Output: False

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/water-and-jug-problem
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

Thought and method:
When you face this problem, you will find that it is more like a math problem, which is easier to complete on paper by extrapolating and giving examples.
Through some examples and experiments, I found that this is the greatest common divisor problem in mathematics, and it is no longer a complex problem in code implementation。
And, of course, if you know Betzu’s theorem, you’ll quickly come to the problem that ax +by=z has a solution if and only if z is a multiple of the greatest common divisor of x and y.
Thus
1、GCD :greatest common divisor

Time complexity: O(log(min(x,y))
depends on the calculation of the maximum common divisor solution, namely, toss and turn phase division.

Space complexity: O(1)

2、DFS
At any given moment, we can only do the following:
Fill the Y pot with water from the X pot until it is full or empty;
Fill the Y pot with water until the X pot is full or empty.
Fill the jug with X;
Fill the Y pot;
Empty the X pot;
Empty the Y pot。

From the above situation,what idea did you think of?
We’re going to be able to try all of these operations, recursively searching down, just like we do depth first with trees.

Time complexity: O(xy).
The maximum number of states is (x+1)(y+1). The time complexity of depth-first search for each state is O(1).Thus O(xy)

Space complexity: O(xy),
same like the time complexity

Code:
1、


 //we can consider it as calculateing the largest common divisor
func canMeasureWater(x int, y int, z int) bool {
	//two speacial situation
    if x + y < z {
		return false
	}
	if x == 0 || y == 0 {
		return x + y == z || z == 0
	}
	return z % GCD(x, y) == 0
}

func GCD(x, y int) int {
	if x % y == 0 {
		return y
	}
	return GCD(y, x%y)
}

2、

var x1, y1, z1 int

func canMeasureWater(x int, y int, z int) bool {
	x1 = x
	y1 = y
	z1 = z
	m := make(map[[2]int]struct{})
	return dfs(&m, 0, 0)
}

func dfs(m *map[[2]int]struct{}, xbottle, ybottle int) bool {
	
    //successful
    if xbottle == z1 || ybottle == z1 || xbottle + ybottle == z1 {
		return true
	}

	//fail
	if _, exist := (*m)[[2]int{xbottle, ybottle}]; exist {
		return false
	}

	(*m)[[2]int{xbottle, ybottle}] = struct{}{}

	return dfs(m, x1, ybottle) ||    //full x 
		dfs(m, xbottle, y1) ||       //full y
		dfs(m, 0, ybottle) ||        //empty x
		dfs(m, xbottle, 0) ||        //empty y
		dfs(m, xbottle-min(xbottle, y1-ybottle), ybottle+min(xbottle, y1-ybottle)) ||  //x pour into y until y is full or x is empty
		dfs(m, xbottle+min(ybottle, x1-xbottle), ybottle-min(ybottle, x1-xbottle))     //y pour into x until x is full or y is empty
}

//min function
func min(a, b int) int {

	if a <= b {
		return a
	} else {
		return b
	}
}

There is no min function applied to int in go, so we need to write it ourselves.
Depth-first takes another function, and you need to make a copy of x,y, and z.I make mistake at first.

Test:
1、
Input: x = 3, y = 5, z = 4
在这里插入图片描述

2、
Input: x = 2, y = 6, z = 5
在这里插入图片描述
在这里插入图片描述
Up:GCD
Down:DFS
By contrast, the mathematical method of finding the greatest common divisor is obviously faster
This also validates the time complexity analysis.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值