Skip to content

Commit 480b0aa

Browse files
authored
feat: add solutions to lc problem: No.0365 (doocs#2266)
No.0365.Water and Jug Problem
1 parent b2a6b78 commit 480b0aa

File tree

9 files changed

+297
-456
lines changed

9 files changed

+297
-456
lines changed

solution/0300-0399/0365.Water and Jug Problem/README.md

+100-153
Original file line numberDiff line numberDiff line change
@@ -51,187 +51,134 @@
5151

5252
## 解法
5353

54-
### 方法一
54+
### 方法一:DFS
55+
56+
我们不妨记 $jug1Capacity$ 为 $x$, $jug2Capacity$ 为 $y$, $targetCapacity$ 为 $z$。
57+
58+
接下来,我们设计一个函数 $dfs(i, j)$,表示当前 $jug1$ 中有 $i$ 升水,$jug2$ 中有 $j$ 升水,是否可以得到 $z$ 升水。
59+
60+
函数 $dfs(i, j)$ 的执行过程如下:
61+
62+
- 如果 $(i, j)$ 已经被访问过,返回 $false$。
63+
- 如果 $i = z$ 或者 $j = z$ 或者 $i + j = z$,返回 $true$。
64+
- 如果我们给 $jug1$ 倒满水,或者给 $jug2$ 倒满水,或者将 $jug1$ 清空,或者将 $jug2$ 清空,可以得到 $z$ 升水,返回 $true$。
65+
- 如果我们将 $jug1$ 中的水倒入 $jug2$,或者将 $jug2$ 中的水倒入 $jug1$,可以得到 $z$ 升水,返回 $true$。
66+
67+
答案即为 $dfs(0, 0)$。
68+
69+
时间复杂度 $O(x + y)$,空间复杂度 $O(x + y)$。其中 $x$ 和 $y$ 分别为 $jug1Capacity$ 和 $jug2Capacity$ 的大小。
5570

5671
<!-- tabs:start -->
5772

5873
```python
5974
class Solution:
60-
def canMeasureWater(
61-
self, jug1Capacity: int, jug2Capacity: int, targetCapacity: int
62-
) -> bool:
63-
stk, seen = [], set()
64-
stk.append([0, 0])
65-
66-
def get_hash(nums):
67-
return nums[0] * 10000006 + nums[1]
68-
69-
while stk:
70-
if get_hash(stk[-1]) in seen:
71-
stk.pop()
72-
continue
73-
seen.add(get_hash(stk[-1]))
74-
cur = stk.pop()
75-
cur1, cur2 = cur[0], cur[1]
76-
if (
77-
cur1 == targetCapacity
78-
or cur2 == targetCapacity
79-
or cur1 + cur2 == targetCapacity
80-
):
75+
def canMeasureWater(self, x: int, y: int, z: int) -> bool:
76+
def dfs(i: int, j: int) -> bool:
77+
if (i, j) in vis:
78+
return False
79+
vis.add((i, j))
80+
if i == z or j == z or i + j == z:
8181
return True
82-
stk.append([jug1Capacity, cur2])
83-
stk.append([0, cur2])
84-
stk.append([cur1, jug2Capacity])
85-
stk.append([cur1, 0])
86-
if cur1 + cur2 > jug1Capacity:
87-
stk.append([jug1Capacity, cur2 - jug1Capacity + cur1])
88-
else:
89-
stk.append([cur1 + cur2, 0])
90-
if cur1 + cur2 > jug2Capacity:
91-
stk.append([cur1 - jug2Capacity + cur2, jug2Capacity])
92-
else:
93-
stk.append([0, cur1 + cur2])
94-
return False
82+
if dfs(x, j) or dfs(i, y) or dfs(0, j) or dfs(i, 0):
83+
return True
84+
a = min(i, y - j)
85+
b = min(j, x - i)
86+
return dfs(i - a, j + a) or dfs(i + b, j - b)
87+
88+
vis = set()
89+
return dfs(0, 0)
9590
```
9691

9792
```java
9893
class Solution {
94+
private Set<Long> vis = new HashSet<>();
95+
private int x, y, z;
96+
9997
public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
100-
Deque<int[]> stk = new ArrayDeque<>();
101-
stk.add(new int[] {0, 0});
102-
Set<Long> seen = new HashSet<>();
103-
while (!stk.isEmpty()) {
104-
if (seen.contains(hash(stk.peek()))) {
105-
stk.pop();
106-
continue;
107-
}
108-
int[] cur = stk.pop();
109-
seen.add(hash(cur));
110-
int cur1 = cur[0], cur2 = cur[1];
111-
if (cur1 == targetCapacity || cur2 == targetCapacity || cur1 + cur2 == targetCapacity) {
112-
return true;
113-
}
114-
stk.offer(new int[] {jug1Capacity, cur2});
115-
stk.offer(new int[] {0, cur2});
116-
stk.offer(new int[] {cur1, jug1Capacity});
117-
stk.offer(new int[] {cur2, 0});
118-
if (cur1 + cur2 > jug1Capacity) {
119-
stk.offer(new int[] {jug1Capacity, cur2 - jug1Capacity + cur1});
120-
} else {
121-
stk.offer(new int[] {cur1 + cur2, 0});
122-
}
123-
if (cur1 + cur2 > jug2Capacity) {
124-
stk.offer(new int[] {cur1 - jug2Capacity + cur2, jug2Capacity});
125-
} else {
126-
stk.offer(new int[] {0, cur1 + cur2});
127-
}
98+
x = jug1Capacity;
99+
y = jug2Capacity;
100+
z = targetCapacity;
101+
return dfs(0, 0);
102+
}
103+
104+
private boolean dfs(int i, int j) {
105+
long st = f(i, j);
106+
if (!vis.add(st)) {
107+
return false;
128108
}
129-
return false;
109+
if (i == z || j == z || i + j == z) {
110+
return true;
111+
}
112+
if (dfs(x, j) || dfs(i, y) || dfs(0, j) || dfs(i, 0)) {
113+
return true;
114+
}
115+
int a = Math.min(i, y - j);
116+
int b = Math.min(j, x - i);
117+
return dfs(i - a, j + a) || dfs(i + b, j - b);
130118
}
131119

132-
public long hash(int[] nums) {
133-
return nums[0] * 10000006L + nums[1];
120+
private long f(int i, int j) {
121+
return i * 1000000L + j;
134122
}
135123
}
136124
```
137125

138126
```cpp
139127
class Solution {
140128
public:
141-
bool canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
142-
if (jug1Capacity + jug2Capacity < targetCapacity) return false;
143-
if (jug1Capacity == 0 || jug2Capacity == 0)
144-
return targetCapacity == 0 || jug1Capacity + jug2Capacity == targetCapacity;
145-
return targetCapacity % gcd(jug1Capacity, jug2Capacity) == 0;
146-
}
147-
148-
int gcd(int a, int b) {
149-
return b == 0 ? a : gcd(b, a % b);
129+
bool canMeasureWater(int x, int y, int z) {
130+
using pii = pair<int, int>;
131+
stack<pii> stk;
132+
stk.emplace(0, 0);
133+
auto hash_function = [](const pii& o) { return hash<int>()(o.first) ^ hash<int>()(o.second); };
134+
unordered_set<pii, decltype(hash_function)> vis(0, hash_function);
135+
while (stk.size()) {
136+
auto st = stk.top();
137+
stk.pop();
138+
if (vis.count(st)) {
139+
continue;
140+
}
141+
vis.emplace(st);
142+
auto [i, j] = st;
143+
if (i == z || j == z || i + j == z) {
144+
return true;
145+
}
146+
stk.emplace(x, j);
147+
stk.emplace(i, y);
148+
stk.emplace(0, j);
149+
stk.emplace(i, 0);
150+
int a = min(i, y - j);
151+
int b = min(j, x - i);
152+
stk.emplace(i - a, j + a);
153+
stk.emplace(i + b, j - b);
154+
}
155+
return false;
150156
}
151157
};
152158
```
153159
154160
```go
155-
func canMeasureWater(jug1Capacity int, jug2Capacity int, targetCapacity int) bool {
156-
if jug1Capacity+jug2Capacity < targetCapacity {
157-
return false
158-
}
159-
if jug1Capacity == 0 || jug2Capacity == 0 {
160-
return targetCapacity == 0 || jug1Capacity+jug2Capacity == targetCapacity
161-
}
162-
163-
var gcd func(a, b int) int
164-
gcd = func(a, b int) int {
165-
if b == 0 {
166-
return a
161+
func canMeasureWater(x int, y int, z int) bool {
162+
type pair struct{ x, y int }
163+
vis := map[pair]bool{}
164+
var dfs func(int, int) bool
165+
dfs = func(i, j int) bool {
166+
st := pair{i, j}
167+
if vis[st] {
168+
return false
167169
}
168-
return gcd(b, a%b)
170+
vis[st] = true
171+
if i == z || j == z || i+j == z {
172+
return true
173+
}
174+
if dfs(x, j) || dfs(i, y) || dfs(0, j) || dfs(i, 0) {
175+
return true
176+
}
177+
a := min(i, y-j)
178+
b := min(j, x-i)
179+
return dfs(i-a, j+a) || dfs(i+b, j-b)
169180
}
170-
return targetCapacity%gcd(jug1Capacity, jug2Capacity) == 0
171-
}
172-
```
173-
174-
```cs
175-
using System;
176-
177-
public class Solution {
178-
public bool CanMeasureWater(int x, int y, int z) {
179-
if (x == 0 || y == 0) return z == x || z == y;
180-
var gcd = GetGcd(x, y);
181-
return z >= 0 && z <= x + y && z % gcd == 0;
182-
}
183-
184-
private int GetGcd(int x, int y)
185-
{
186-
while (x > 0)
187-
{
188-
var quotient = x / y;
189-
var reminder = x % y;
190-
if (reminder == 0)
191-
{
192-
return y;
193-
}
194-
x = y;
195-
y = reminder;
196-
}
197-
throw new Exception("Invalid x or y");
198-
}
199-
}
200-
```
201-
202-
<!-- tabs:end -->
203-
204-
### 方法二
205-
206-
<!-- tabs:start -->
207-
208-
```python
209-
class Solution:
210-
def canMeasureWater(
211-
self, jug1Capacity: int, jug2Capacity: int, targetCapacity: int
212-
) -> bool:
213-
if jug1Capacity + jug2Capacity < targetCapacity:
214-
return False
215-
if jug1Capacity == 0 or jug2Capacity == 0:
216-
return targetCapacity == 0 or jug1Capacity + jug2Capacity == targetCapacity
217-
return targetCapacity % gcd(jug1Capacity, jug2Capacity) == 0
218-
```
219-
220-
```java
221-
class Solution {
222-
public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
223-
if (jug1Capacity + jug2Capacity < targetCapacity) {
224-
return false;
225-
}
226-
if (jug1Capacity == 0 || jug2Capacity == 0) {
227-
return targetCapacity == 0 || jug1Capacity + jug2Capacity == targetCapacity;
228-
}
229-
return targetCapacity % gcd(jug1Capacity, jug2Capacity) == 0;
230-
}
231-
232-
private int gcd(int a, int b) {
233-
return b == 0 ? a : gcd(b, a % b);
234-
}
181+
return dfs(0, 0)
235182
}
236183
```
237184

0 commit comments

Comments
 (0)