【力扣每日一题】力扣365水壶问题

题目来源

力扣365水壶问题icon-default.png?t=N7T8https://leetcode.cn/problems/water-and-jug-problem/description/

题目概述

有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 targetCapacity 升。

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

你可以:

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

解题思路

首先我们确定在实际上我们只能做的操作:

  1. 把其中一个杯子装满;
  2. 把一个杯子里的水倒入另一个杯子,然后清空那个满的杯子(清空不满的杯子没有意义,我们可以直接装满一个杯子,哈哈哈哈)。

我们记水的总量为sum,sum = a × jug1Capacity + b × jug2Capacity。(a >= 0 && b >= 0)。 由此可知,我们会有无穷多个计算sum的表达式。 当某一个sum == targetCapacity时我们应该返回结果为true,这时可以使用贝祖定理(裴蜀定理)来解决问题:

对任意两个整数a、b设d是它们的最大公约数。ax + by = m有整数解(x,y)当且仅当m是d的倍数。

总结

我们只需要确定targetCapacityjug1Capacityjug2Capacity的最大公约数的倍数,那就返回结果true,反之返回false。 关于求最大公约数的题目以前做过可以使用欧几里德算法求。【每日一题博客】力扣2807在链表中插入最大公约数

代码实现

java实现

public class Solution {
    public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
        // 如果两个杯子都装满也不够
        if (jug1Capacity + jug2Capacity < targetCapacity) {
            return false;
        }
        // 欧几里得算法求最大公约数
        int remainder = jug1Capacity % jug2Capacity;
        while (remainder != 0) {
            jug1Capacity = jug2Capacity;
            jug2Capacity = remainder;
            remainder = jug1Capacity % jug2Capacity;
        }
        // 最终jug2保存的是两个容量的最小公约数
        return targetCapacity % jug2Capacity == 0;
    }
}

c++实现

这里c++的代码跟java完全一样的

class Solution {
public:
    bool canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {
        // 如果两个杯子都装满也不够
        if (jug1Capacity + jug2Capacity < targetCapacity) {
            return false;
        }
        // 使用欧几里得算法求最大公约数
        int remainder = jug1Capacity % jug2Capacity;
        while (remainder != 0) {
            jug1Capacity = jug2Capacity;
            jug2Capacity = remainder;
            remainder = jug1Capacity % jug2Capacity;
        }
        // 最终jug2保存的是两个容量的最小公约数
        return targetCapacity % jug2Capacity == 0;
    }
};

你可能感兴趣的:(leetcode,算法,java,c++)