• LeetCode 37.水壶问题 数学方法与广度遍历


    题目描述

     

    有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?

    如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。

    你允许:

    • 装满任意一个水壶
    • 清空任意一个水壶
    • 从一个水壶向另外一个水壶倒水,直到装满或者倒空

    示例 1: (From the famous "Die Hard" example)

    输入: x = 3, y = 5, z = 4
    输出: True
    

    示例 2:

    输入: x = 2, y = 6, z = 5
    输出: False

    解题思路

     数学方法:找到x,y的最大公约数能否z被整除

    BFS:将水壶x,y的相关操作分解为6个状态,分别为 // 1.给x装满水 // 2.给y装满水 // 3.清空x的水 // 4.清空y的水 // 5.x向y倒水,直到x空或者y满 // 6.y向x倒水,直到y空或者x满 // 通过不断的搜索,如果x,y中的水满足 // x == z || y == z || x + y == z 返回true,否则继续搜索直到所有情况都搜索完毕

    代码如下

    数学方法:

     

    复制代码
    public boolean canMeasureWater(int x, int y, int z) {
               if(x+y<z){
                    return false;
                }
                if(x == 0 || y == 0){
                    return z==0 || x+y==z;
                }
                return z % gcb(x,y) == 0;
            }
            int gcb(int m, int n) {  
                    if (m < n) {// 保证m>n,若m<n,则进行数据交换  
                        int temp = m;  
                        m = n;  
                        n = temp;  
                    }  
                    if (m % n == 0) {// 若余数为0,返回最大公约数  
                        return n;  
                    } else { // 否则,进行递归,把n赋给m,把余数赋给n  
                        return gcb(n, m % n);  
                    } 
    
            }
    复制代码

     

    BFS:

    复制代码
    public boolean canMeasureWater(int x, int y, int z) {
       
            if (z > x + y) return false;
            if (x == z || y == z || x + y == z) return true;
    
            // 保存搜索过的情况,防止无止境的搜索下去
            Set<List<Integer>> set = new HashSet<>();
    
            // 保存每次操作后,x,y中剩余的水的容量
            LinkedList<List<Integer>> res = new LinkedList<>();
    
            // 初始时,x y中均没有水
            List<Integer> list = Arrays.asList(0, 0);
            set.add(list);
            res.add(list);
    
            while (!res.isEmpty()) {
                List<Integer> poll = res.poll();
                int remain_x = poll.get(0);
                int remain_y = poll.get(1);
                if (remain_x == z || remain_y == z || remain_x + remain_y == z) {
                    return true;
                }
    
                // 给x加满水
                List<Integer> p1 = Arrays.asList(x, remain_y);
                if (!set.contains(p1)) {
                    set.add(p1);
                    res.add(p1);
                }
    
                // 给y加满水
                List<Integer> p2 = Arrays.asList(remain_x, y);
                if (!set.contains(p2)) {
                    set.add(p2);
                    res.add(p2);
                }
    
    
                // 清空x的水
                List<Integer> p3 = Arrays.asList(0, remain_y);
                if (!set.contains(p3)) {
                    set.add(p3);
                    res.add(p3);
                }
    
                // 清空y的水
                List<Integer> p4 = Arrays.asList(remain_x, 0);
                if (!set.contains(p4)) {
                    set.add(p4);
                    res.add(p4);
                }
    
                // x向y倒水
                int tmp_x = (remain_x + remain_y) <= y ? 0 : remain_x + remain_y - y;
                int tmp_y = (remain_x + remain_y) < y ? remain_x + remain_y : y;
                List<Integer> p5 = Arrays.asList(tmp_x, tmp_y);
                if (!set.contains(p5)) {
                    set.add(p5);
                    res.add(p5);
                }
    
    
                // y向x倒水
                tmp_y = (remain_x + remain_y) <= x ? 0 : remain_x + remain_y - x;
                tmp_x = (remain_x + remain_y) < x ? remain_x + remain_y : x;
                List<Integer> p6 = Arrays.asList(tmp_x, tmp_y);
                if (!set.contains(p6)) {
                    set.add(p6);
                    res.add(p6);
                }
    
            }
    
            return false;
        }
    参考自:LeetCode用户yw-git

     

    
    
    复制代码

     

  • 相关阅读:
    iOS项目之wifi局域网传输文件到iPhone的简单实现
    iOS项目之苹果审核被拒
    iOS项目之模拟请求数据
    nvm-window常用命令
    初探浏览器渲染原理
    node + mongodb 简单实现自己的查询接口
    快速理解_.debounce方法
    tr标签使用hover的box-shadow效果不生效
    一个简单的Node命令行程序:文件浏览
    打造丝般顺滑的 H5 翻页库(传送门)
  • 原文地址:https://www.cnblogs.com/Transkai/p/12574316.html
Copyright © 2020-2023  润新知