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.