Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 480b0aa

Browse files
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‎

Lines changed: 100 additions & 153 deletions
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(inti, intj) {
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)

AltStyle によって変換されたページ (->オリジナル) /