有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 targetCapacity 升。
如果可以得到 targetCapacity 升水,最后请用以上水壶中的一或两个来盛放取得的 targetCapacity 升水。
你可以:
装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空
示例 1:
输入: jug1Capacity = 3, jug2Capacity = 5, targetCapacity = 4
输出: true
解释:来自著名的 "Die Hard"
示例 2:
输入: jug1Capacity = 2, jug2Capacity = 6, targetCapacity = 5
输出: false
示例 3:
输入: jug1Capacity = 1, jug2Capacity = 2, targetCapacity = 3
输出: true
提示:
1 <= jug1Capacity, jug2Capacity, targetCapacity <= 106
code:
public class CanMeasureWater {
// 365. 水壶问题
public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
if (targetCapacity > jug1Capacity + jug2Capacity) {
return false;
}
Deque<int[]> stack = new LinkedList<int[]>();
stack.push(new int[]{0, 0});
Set<Long> isContain = new HashSet<>();
while (!stack.isEmpty()) {
int[] remain = stack.peek();
stack.pop();
int remainX = remain[0];
int remainY = remain[1];
if (isContain.contains(getHashValue(remainX, remainY))) {
continue;
}
isContain.add(getHashValue(remainX, remainY));
if (remainX == targetCapacity || remainY == targetCapacity || remainX + remainY == targetCapacity) {
return true;
}
stack.push(new int[]{remainX, jug2Capacity});
stack.push(new int[]{jug1Capacity, remainY});
stack.push(new int[]{0, remainY});
stack.push(new int[]{remainX, 0});
stack.push(new int[]{remainX + Math.min(jug1Capacity - remainX, remainY), remainY - Math.min(jug1Capacity - remainX, remainY)});
stack.push(new int[]{remainX - Math.min(remainX, jug2Capacity - remainY), remainY + Math.min(remainX, jug2Capacity - remainY)});
}
return false;
}
private long getHashValue(int x, int y) {
return (long) x * 1000000L + y;
}
public static void main(String[] args) {
CanMeasureWater solution = new CanMeasureWater();
System.out.println(solution.canMeasureWater(3, 5, 4));
}
}