leetcode 力扣 365 水壶问题题解 算法题.docx

上传人:b****3 文档编号:4125251 上传时间:2022-11-28 格式:DOCX 页数:15 大小:19.65KB
下载 相关 举报
leetcode 力扣 365 水壶问题题解 算法题.docx_第1页
第1页 / 共15页
leetcode 力扣 365 水壶问题题解 算法题.docx_第2页
第2页 / 共15页
leetcode 力扣 365 水壶问题题解 算法题.docx_第3页
第3页 / 共15页
leetcode 力扣 365 水壶问题题解 算法题.docx_第4页
第4页 / 共15页
leetcode 力扣 365 水壶问题题解 算法题.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

leetcode 力扣 365 水壶问题题解 算法题.docx

《leetcode 力扣 365 水壶问题题解 算法题.docx》由会员分享,可在线阅读,更多相关《leetcode 力扣 365 水壶问题题解 算法题.docx(15页珍藏版)》请在冰豆网上搜索。

leetcode 力扣 365 水壶问题题解 算法题.docx

leetcode力扣365水壶问题题解算法题

题目:

水壶问题

有两个容量分别为 x升和y升的水壶以及无限多的水。

请判断能否通过使用这两个水壶,从而可以得到恰好 z升的水?

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

你允许:

•装满任意一个水壶

•清空任意一个水壶

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

示例1:

(Fromthefamous"DieHard"example)

输入:

x=3,y=5,z=4

输出:

True

示例2:

输入:

x=2,y=6,z=5

输出:

False

语言:

Python

classSolution:

defcanMeasureWater(self,x:

int,y:

int,z:

int)->bool:

stack=[(0,0)]

self.seen=set()

whilestack:

remain_x,remain_y=stack.pop()

ifremain_x==zorremain_y==zorremain_x+remain_y==z:

returnTrue

if(remain_x,remain_y)inself.seen:

continue

self.seen.add((remain_x,remain_y))

#把X壶灌满。

stack.append((x,remain_y))

#把Y壶灌满。

stack.append((remain_x,y))

#把X壶倒空。

stack.append((0,remain_y))

#把Y壶倒空。

stack.append((remain_x,0))

#把X壶的水灌进Y壶,直至灌满或倒空。

stack.append((remain_x-min(remain_x,y-remain_y),remain_y+min(remain_x,y-remain_y)))

#把Y壶的水灌进X壶,直至灌满或倒空。

stack.append((remain_x+min(remain_y,x-remain_x),remain_y-min(remain_y,x-remain_x)))

returnFalse

语言:

Python

classSolution:

defcanMeasureWater(self,x:

int,y:

int,z:

int)->bool:

ifx+y

returnFalse

ifx==0ory==0:

returnz==0orx+y==z

returnz%math.gcd(x,y)==0

语言:

C++

usingPII=pair;

classSolution{

public:

boolcanMeasureWater(intx,inty,intz){

stackstk;

stk.emplace(0,0);

autohash_function=[](constPII&o){returnhash()(o.first)^hash()(o.second);};

unordered_setseen(0,hash_function);

while(!

stk.empty()){

if(seen.count(stk.top())){

stk.pop();

continue;

}

seen.emplace(stk.top());

auto[remain_x,remain_y]=stk.top();

stk.pop();

if(remain_x==z||remain_y==z||remain_x+remain_y==z){

returntrue;

}

//把X壶灌满。

stk.emplace(x,remain_y);

//把Y壶灌满。

stk.emplace(remain_x,y);

//把X壶倒空。

stk.emplace(0,remain_y);

//把Y壶倒空。

stk.emplace(remain_x,0);

//把X壶的水灌进Y壶,直至灌满或倒空。

stk.emplace(remain_x-min(remain_x,y-remain_y),remain_y+min(remain_x,y-remain_y));

//把Y壶的水灌进X壶,直至灌满或倒空。

stk.emplace(remain_x+min(remain_y,x-remain_x),remain_y-min(remain_y,x-remain_x));

}

returnfalse;

}

};

语言:

C++

classSolution{

public:

boolcanMeasureWater(intx,inty,intz){

if(x+y

returnfalse;

}

if(x==0||y==0){

returnz==0||x+y==z;

}

returnz%gcd(x,y)==0;

}

};

语言:

C++

classSolution{

inlinepairop(inttype,constpair&state,intx,inty){

switch(type){

case0:

returnmake_pair(x,state.second);

case1:

returnmake_pair(state.first,y);

case2:

returnmake_pair(0,state.second);

case3:

returnmake_pair(state.first,0);

case4:

{

intmove=min(state.first,y-state.second);

returnmake_pair(state.first-move,state.second+move);

}

case5:

{

intmove=min(x-state.first,state.second);

returnmake_pair(state.first+move,state.second-move);

}

}

returnmake_pair(0,0);

}

structHashPair{

size_toperator()(constpair&key)constnoexcept

{

return(size_t(key.first)<<31)|size_t(key.second);

}

};

inlineint64_tHash(intx,inty){

returnint64_t(x)<<32|y;

}

public:

boolcanMeasureWater(intx,inty,intz){

if(x+y

returnfalse;

}

unordered_setmark;//pair换成int64_t,但是意义不大。

queue>q;

q.push(make_pair(0,0));

while(q.empty()==false){

autof=q.front();

q.pop();

if(f.first+f.second==z){

returntrue;

}

for(inti=0;i<6;i++){

autonext=op(i,f,x,y);

int64_th=Hash(next.first,next.second);

if(mark.find(h)!

=mark.end()){

continue;

}

mark.insert(h);

q.push(next);

}

}

returnfalse;

}

};

语言:

Java

classSolution{

publicbooleancanMeasureWater(intx,inty,intz){

Dequestack=newLinkedList();

stack.push(newint[]{0,0});

Setseen=newHashSet();

while(!

stack.isEmpty()){

if(seen.contains(hash(stack.peek()))){

stack.pop();

continue;

}

seen.add(hash(stack.peek()));

int[]state=stack.pop();

intremain_x=state[0],remain_y=state[1];

if(remain_x==z||remain_y==z||remain_x+remain_y==z){

returntrue;

}

//把X壶灌满。

stack.push(newint[]{x,remain_y});

//把Y壶灌满。

stack.push(newint[]{remain_x,y});

//把X壶倒空。

stack.push(newint[]{0,remain_y});

//把Y壶倒空。

stack.push(newint[]{remain_x,0});

//把X壶的水灌进Y壶,直至灌满或倒空。

stack.push(newint[]{remain_x-Math.min(remain_x,y-remain_y),remain_y+Math.min(remain_x,y-remain_y)});

//把Y壶的水灌进X壶,直至灌满或倒空。

stack.push(newint[]{remain_x+Math.min(remain_y,x-remain_x),remain_y-Math.min(remain_y,x-remain_x)});

}

returnfalse;

}

publiclonghash(int[]state){

return(long)state[0]*1000001+state[1];

}

}

语言:

Java

classSolution{

publicbooleancanMeasureWater(intx,inty,intz){

if(x+y

returnfalse;

}

if(x==0||y==0){

returnz==0||x+y==z;

}

returnz%gcd(x,y)==0;

}

publicintgcd(intx,inty){

intremainder=x%y;

while(remainder!

=0){

x=y;

y=remainder;

remainder=x%y;

}

returny;

}

}

语言:

Java

importjava.util.ArrayList;

importjava.util.HashSet;

importjava.util.LinkedList;

importjava.util.List;

importjava.util.Objects;

importjava.util.Queue;

importjava.util.Set;

publicclassSolution{

publicbooleancanMeasureWater(intx,inty,intz){

//特判

if(z==0){

returntrue;

}

if(x+y

returnfalse;

}

StateinitState=newState(0,0);

//广度优先遍历使用队列

Queuequeue=newLinkedList<>();

Setvisited=newHashSet<>();

queue.offer(initState);

visited.add(initState);

while(!

queue.isEmpty()){

Statehead=queue.poll();

intcurX=head.getX();

intcurY=head.getY();

//curX+curY==z比较容易忽略

if(curX==z||curY==z||curX+curY==z){

returntrue;

}

//从当前状态获得所有可能的下一步的状态

ListnextStates=getNextStates(curX,curY,x,y);

//打开以便于观察,调试代码

//System.out.println(head+"=>"+nextStates);

for(StatenextState:

nextStates){

if(!

visited.contains(nextState)){

queue.offer(nextState);

//添加到队列以后,必须马上设置为已经访问,否则会出现死循环

visited.add(nextState);

}

}

}

returnfalse;

}

privateListgetNextStates(intcurX,intcurY,intx,inty){

//最多8个对象,防止动态数组扩容,不过Java默认的初始化容量肯定大于8个

ListnextStates=newArrayList<>(8);

//按理说应该先判断状态是否存在,再生成「状态」对象,这里为了阅读方便,一次生成8个对象

//以下两个状态,对应操作1

//外部加水,使得A满

StatenextState1=newState(x,curY);

//外部加水,使得B满

StatenextState2=newState(curX,y);

//以下两个状态,对应操作2

//把A清空

StatenextState3=newState(0,curY);

//把B清空

StatenextState4=newState(curX,0);

//以下四个状态,对应操作3

//从A到B,使得B满,A还有剩

StatenextState5=newState(curX-(y-curY),y);

//从A到B,此时A的水太少,A倒尽,B没有满

StatenextState6=newState(0,curX+curY);

//从B到A,使得A满,B还有剩余

StatenextState7=newState(x,curY-(x-curX));

//从B到A,此时B的水太少,B倒尽,A没有满

StatenextState8=newState(curX+curY,0);

//没有满的时候,才需要加水

if(curX

nextStates.add(nextState1);

}

if(curY

nextStates.add(nextState2);

}

//有水的时候,才需要倒掉

if(curX>0){

nextStates.add(nextState3);

}

if(curY>0){

nextStates.add(nextState4);

}

//有剩余才倒

if(curX-(y-curY)>0){

nextStates.add(nextState5);

}

if(curY-(x-curX)>0){

nextStates.add(nextState7);

}

//倒过去倒不满才倒

if(curX+curY

nextStates.add(nextState6);

}

if(curX+curY

nextStates.add(nextState8);

}

returnnextStates;

}

privateclassState{

privateintx;

privateinty;

publicState(intx,inty){

this.x=x;

this.y=y;

}

publicintgetX(){

returnx;

}

publicintgetY(){

returny;

}

@Override

publicStringtoString(){

return"State{"+

"x="+x+

",y="+y+

'}';

}

@Override

publicbooleanequals(Objecto){

if(this==o){

returntrue;

}

if(o==null||getClass()!

=o.getClass()){

returnfalse;

}

Statestate=(State)o;

returnx==state.x&&

y==state.y;

}

@Override

publicinthashCode(){

returnObjects.hash(x,y);

}

}

publicstaticvoidmain(String[]args){

Solutionsolution=newSolution();

intx=3;

inty=5;

intz=4;

//intx=2;

//inty=6;

//intz=5;

//intx=1;

//inty=2;

//intz=3;

booleanres=solution.canMeasureWater(x,y,z);

System.out.println(res);

}

}

语言:

php

classSolution{

/**

*@paramInteger$x

*@paramInteger$y

*@paramInteger$z

*@returnBoolean

*/

//贝祖定理

functioncanMeasureWater($x,$y,$z){

if($x+$y<$z)returnfalse;

if($x==0||$y==0)return$z==0||$x+$y==$z;

//x,y不为0,那么公约数$gcd最小为1,不需要判断为0

$gcd=$this->gcd($x,$y);

return($z%$gcd)==0?

true:

false;//比fmod快

}

//欧几里得算法

functiongcd($n,$m){

if(!

$m)return$n;

return$this->gcd($m,($n%$m));

}

}

语言:

go

funccanMeasureWater(xint,yint,zint)bool{

ifz==0||z==x+y{//条件1

returntrue

}elseifz>x+y||y==0{//条件2和3

returnfalse

}

//迭代公式2、4、6

returncanMeasureWater(y,x%y,z%y)

}

语言:

go

funccanMeasureWater(xint,yint,zint)bool{

for;z!

=0&&y!

=0&&z

}

returnz==0||z==x+y

}

语言:

js

/**

*@param{number}x

*@param{number}y

*@param{number}z

*@return{boolean}

*/

varcanMeasureWater=function(x,y,z){

if(x+y

if(z===0)returntrue;

if(x===0)returny===z;

if(y===0)returnx===z;

functionGCD(a,b){

letmin=Math.min(a,b);

while(min){

if(a%min===0&&b%min===0)returnmin;

min--;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1