leetcode 力扣 365 水壶问题题解 算法题.docx
- 文档编号:4125251
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:15
- 大小:19.65KB
leetcode 力扣 365 水壶问题题解 算法题.docx
《leetcode 力扣 365 水壶问题题解 算法题.docx》由会员分享,可在线阅读,更多相关《leetcode 力扣 365 水壶问题题解 算法题.docx(15页珍藏版)》请在冰豆网上搜索。
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){ stack stk.emplace(0,0); autohash_function=[](constPII&o){returnhash unordered_set 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{ inlinepair 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 { 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_set queue 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){ Deque stack.push(newint[]{0,0}); Set 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); //广度优先遍历使用队列 Queue Set 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; } //从当前状态获得所有可能的下一步的状态 List //打开以便于观察,调试代码 //System.out.println(head+"=>"+nextStates); for(StatenextState: nextStates){ if(! visited.contains(nextState)){ queue.offer(nextState); //添加到队列以后,必须马上设置为已经访问,否则会出现死循环 visited.add(nextState); } } } returnfalse; } privateList //最多8个对象,防止动态数组扩容,不过Java默认的初始化容量肯定大于8个 List //按理说应该先判断状态是否存在,再生成「状态」对象,这里为了阅读方便,一次生成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--;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- leetcode 力扣 365 水壶问题 题解 算法题 水壶 问题 算法