1.水壶问题

leetcode 水壶问题


难度 中等

 


有两个容量分别为 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

 

解题思路

这个问题当然很容易想到用

z=a*x+b*y(a,b均整数)表示啦,但是怎么用编程语言来描述这个公式呢?

 

我一开始想用x与y的差值来表示z,通过设置a与b的值

然而这种方法很naive,a与b的设置方式有成千上万种,设置起来十分麻烦,如果用穷举法,耗时长,还不一定找得到

我错误的原因是忘记了这一点,把a,b关系想的太简单,结果对a,b设置错误

错误的算法:选出x,y中的max与min,设置a=1自增(即a为整数)

在a*min<max情况下,如果abs(a*min-max)==z,则可以。

不知道怎么想的,a,b关系也太简单了吧,还是没有好好想想

 

后来从别人的文章中发现

如果z=a*x+b*y(a,b均整),x与y最大公约数为g,那么z一定是g的整数倍,即z%g=0!!

??!

这不是小学初中就教过吗,

就算没教过,想想也知道

a*x=a*n*g,b*y=b*m*g,如果z=(a*n+b*m)g,那z可不就是g的整数倍吗敲打

 

居然没想到,-_-||

 

g还不好求吗,辗转相除法的事

 

代码

 

class Solution {
public boolean canMeasureWater(int x, int y, int z) {
        return z == 0 || (x + y >= z && z % gcd(x, y) == 0);
    }
    int gcd(int x, int y) {
        return y == 0 ? x : gcd(y, x % y);
    }
}

 

 

总结

又浪费了几个小时,解法却这么简单,智商受到碾压

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值