【经典算法题】水壶问题
【经典算法题】水壶问题
Leetcode 0365 水壶问题
题目描述:Leetcode 0365 水壶问题

分析
-
本题的考点:数学、欧几里得算法。
-
两个水壶记为
A、B。A、B这两个水壶都是及不空也不满,这种情况是不可能存在的。这是因为我们的三种操作所决定的。 -
我们考虑将两个水壶看成一体,考虑整个整体和外界交换的水量,在最优操作情况下(即操作次数最少的情况下),每次和外界交换的水量只可能是
+x、-x、+y、-y。原因如下:假设现在A中有水但是不满,则B中要么是空要么是满,此时将A加满或者将A倒空和外界交换的水量不是上述情况,如果这样操作可以得到解,不如上来直接让A为空或者为满,这样操作次数更少。 -
考虑这个整体和外界交换水量为
x、y的次数分别为a、b,如果有 a × x + b × y = = z a \times x + b \times y ==z a×x+b×y==z,则说明存在解。 -
因此我们需要判断是否存在这样的
a、b使得 a × x + b × y = = z a \times x + b \times y ==z a×x+b×y==z,这就是裴淑定理。可以参考:扩展欧几里得算法。 -
这里如果
x、y的最大公约数可以整除c,就存在a、b。 -
那我们能构造出这组解吗?如果
z>x+y,说明一定不存在解。否则可以构造出这组解。下面给出构造过程:(1)首先
a、b不可能都小于0,因为右侧是c是大于0的,如果a、b都大于0,则说明a、b都等于1,z=x+y;(2)当有一个大于0,一个小于等于0时,比如
a>0,b<=0,则我们可以向A中加满水,然后将A中的水倒到B中,直到水壶A被加了a次水,水壶B倒掉了b次水既可以得到结果。
代码
- C++
class Solution {
public:
bool canMeasureWater(int x, int y, int z) {
if (z > x + y) return false;
return !z || z % gcd(x, y) == 0;
}
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
};
- Java
class Solution {
public boolean canMeasureWater(int x, int y, int z) {
if (z > x + y) return false;
return z == 0 || z % gcd(x, y) == 0;
}
private int gcd(int a, int b) {
return b != 0 ? gcd(b, a % b) : a;
}
}
时空复杂度分析
-
时间复杂度: O ( l o g ( n ) ) O(log(n)) O(log(n)),
n为求最大公约数的数的大小。 -
空间复杂度: O ( 1 ) O(1) O(1)。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)