对于这种问题,通常可以通过分析出所有的操作类型解决,比如对于这个水壶问题来说,分析可知对于每一刻来说,只会有六种操作类型,分别是:
- 第一个水壶装满水
- 第二个水壶装满水
- 第一个水壶清空
- 第二个水壶清空
- 将第一个水壶的水倒向第二个水壶
- 将第二个水壶的水倒向低一个水壶
那么就可以进行深度搜索求解
class Solution {
public Boolean flag = false;
public boolean canMeasureWater(int x, int y, int target) {
if(x + y < target){
return false;
}
dfs(0,0,x,y,target,new HashSet<>());
return flag;
}
/**
*
* @param a 第一个杯子当前的水
* @param b 第二个被子当前的水
* @param x
* @param y
* @param target
* @param flag
* @param vis
*/
public void dfs(int a, int b, int x, int y, int target, Set<String> vis){
if(a == target || b == target || a == target || b == target || a+b == target){
this.flag = true;
}
String now = a + " " + b;
if(vis.contains(now)){
return;
}
vis.add(now);
dfs(0,b,x,y,target,vis);
dfs(a,0,x,y,target,vis);
dfs(x,b,x,y,target,vis);
dfs(a,y,x,y,target,vis);
// 把第一个杯子的水倒到第二个杯子
int newa = Math.max(0,a-y+b);
int newb = Math.min(y,a+b);
dfs(newa,newb,x,y,target,vis);
newa = Math.min(x,a+b);
newb = Math.max(0,b-x+a);
dfs(newa,newb,x,y,target,vis);
}
}
同时也可以记录下具体的操作步骤:
public boolean canMeasureWater(int x, int y, int target) {
if(x + y < target){
return false;
}
List<String> dfs = dfs(x, y, 0, 0, target, new ArrayList<String>(),new HashSet<String>());
if(dfs == null){
return false;
}
return true;
}
/**
*
* @param x
* @param y
* @param a 第一个水壶当前水量
* @param b 第二个水壶当前水量
* @param target
* @param path 结果方法
* @return
*/
public List<String> dfs(int x, int y, int a, int b, int target, List<String> path, Set<String> vis){
if(a == target || b == target || a + b == target){
return path;
}
if(vis.contains(a+","+b)){
return null;
}
vis.add(a+","+b);
/**
* one : 第一个水壶倒满水
* two : 第二个水壶倒满水
* three : 第一个水壶清空水
* four : 第二个水壶清空水
* five : 第一个水壶的水倒向第二个水壶
* six : 第二个水壶的水倒向第一个水壶
*/
path.add("one");
List<String> res = dfs(x, y, x, b, target, path,vis);
if(res != null){
return res;
}
path.remove("one");
path.add("two");
res = dfs(x, y, a, y, target, path,vis);
if(res!= null){
return res;
}
path.remove("two");
path.add("three");
res = dfs(x, y, 0, b, target, path,vis);
if(res!= null){
return res;
}
path.remove("three");
path.add("four");
res = dfs(x, y, a, 0, target, path,vis);
if(res!= null){
return res;
}
path.remove("four");
path.add("five");
int newa = Math.max(0,a-(y-b));
int newb = Math.min(y,b + a);
res = dfs(x, y, newa, newb, target, path,vis);
if(res!= null){
return res;
}
path.remove("five");
path.add("six");
newa = Math.min(x,a+b);
newb = Math.max(0,b-(x-a));
res = dfs(x,y,newa,newb, target, path,vis);
if(res!= null){
return res;
}
path.remove("six");
return null;
}