水壶问题——深搜

62 阅读2分钟

leetcode.cn/problems/wa…

在这里插入图片描述

对于这种问题,通常可以通过分析出所有的操作类型解决,比如对于这个水壶问题来说,分析可知对于每一刻来说,只会有六种操作类型,分别是:

  1. 第一个水壶装满水
  2. 第二个水壶装满水
  3. 第一个水壶清空
  4. 第二个水壶清空
  5. 将第一个水壶的水倒向第二个水壶
  6. 将第二个水壶的水倒向低一个水壶

那么就可以进行深度搜索求解

 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;
     }
 ​