leetcode 力扣 365 水壶问题题解 算法题Word文档格式.docx
- 文档编号:17041266
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:15
- 大小:19.65KB
leetcode 力扣 365 水壶问题题解 算法题Word文档格式.docx
《leetcode 力扣 365 水壶问题题解 算法题Word文档格式.docx》由会员分享,可在线阅读,更多相关《leetcode 力扣 365 水壶问题题解 算法题Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
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
ifx+y<
z:
ifx==0ory==0:
returnz==0orx+y==z
returnz%math.gcd(x,y)==0
C++
usingPII=pair<
int,int>
;
classSolution{
public:
boolcanMeasureWater(intx,inty,intz){
stack<
PII>
stk;
stk.emplace(0,0);
autohash_function=[](constPII&
o){returnhash<
int>
()(o.first)^hash<
()(o.second);
};
unordered_set<
PII,decltype(hash_function)>
seen(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();
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;
if(x+y<
z){
if(x==0||y==0){
returnz==0||x+y==z;
returnz%gcd(x,y)==0;
inlinepair<
op(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;
if(x+y<
z){//加了一个很蠢的剪枝,作用比较大。
int64_t>
mark;
//pair<
换成int64_t,但是意义不大。
queue<
pair<
int,int>
>
q;
q.push(make_pair(0,0));
while(q.empty()==false){
autof=q.front();
q.pop();
if(f.first+f.second==z){
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()){
mark.insert(h);
q.push(next);
Java
publicbooleancanMeasureWater(intx,inty,intz){
Deque<
int[]>
stack=newLinkedList<
();
stack.push(newint[]{0,0});
Set<
Long>
seen=newHashSet<
stack.isEmpty()){
if(seen.contains(hash(stack.peek()))){
stack.pop();
seen.add(hash(stack.peek()));
int[]state=stack.pop();
intremain_x=state[0],remain_y=state[1];
stack.push(newint[]{x,remain_y});
stack.push(newint[]{remain_x,y});
stack.push(newint[]{0,remain_y});
stack.push(newint[]{remain_x,0});
stack.push(newint[]{remain_x-Math.min(remain_x,y-remain_y),remain_y+Math.min(remain_x,y-remain_y)});
stack.push(newint[]{remain_x+Math.min(remain_y,x-remain_x),remain_y-Math.min(remain_y,x-remain_x)});
publiclonghash(int[]state){
return(long)state[0]*1000001+state[1];
}
publicintgcd(intx,inty){
intremainder=x%y;
while(remainder!
=0){
x=y;
y=remainder;
remainder=x%y;
returny;
importjava.util.ArrayList;
importjava.util.HashSet;
importjava.util.LinkedList;
importjava.util.List;
importjava.util.Objects;
importjava.util.Queue;
importjava.util.Set;
publicclassSolution{
//特判
if(z==0){
StateinitState=newState(0,0);
//广度优先遍历使用队列
Queue<
State>
queue=newLinkedList<
visited=newHashSet<
queue.offer(initState);
visited.add(initState);
queue.isEmpty()){
Statehead=queue.poll();
intcurX=head.getX();
intcurY=head.getY();
//curX+curY==z比较容易忽略
if(curX==z||curY==z||curX+curY==z){
//从当前状态获得所有可能的下一步的状态
List<
nextStates=getNextStates(curX,curY,x,y);
//打开以便于观察,调试代码
//System.out.println(head+"
=>
"
+nextStates);
for(StatenextState:
nextStates){
if(!
visited.contains(nextState)){
queue.offer(nextState);
//添加到队列以后,必须马上设置为已经访问,否则会出现死循环
visited.add(nextState);
privateList<
getNextStates(intcurX,intcurY,intx,inty){
//最多8个对象,防止动态数组扩容,不过Java默认的初始化容量肯定大于8个
nextStates=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<
x){
nextStates.add(nextState1);
if(curY<
y){
nextStates.add(nextState2);
//有水的时候,才需要倒掉
if(curX>
0){
nextStates.add(nextState3);
if(curY>
nextStates.add(nextState4);
//有剩余才倒
if(curX-(y-curY)>
nextStates.add(nextState5);
if(curY-(x-curX)>
nextStates.add(nextState7);
//倒过去倒不满才倒
if(curX+curY<
nextStates.add(nextState6);
nextStates.add(nextState8);
returnnextStates;
privateclassState{
privateintx;
privateinty;
publicState(intx,inty){
this.x=x;
this.y=y;
publicintgetX(){
returnx;
publicintgetY(){
@Override
publicStringtoString(){
return"
State{"
+
x="
+x+
y="
+y+
'
}'
publicbooleanequals(Objecto){
if(this==o){
if(o==null||getClass()!
=o.getClass()){
Statestate=(State)o;
returnx==state.x&
&
y==state.y;
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
/**
*@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)
for;
z!
=0&
y!
z<
x+y;
x,y,z=y,x%y,z%y{
returnz==0||z==x+y
js
/**
*@param{number}x
*@param{number}y
*@param{number}z
*@return{boolean}
varcanMeasureWater=function(x,y,z){
z)returnfalse;
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 水壶问题 题解 算法题 水壶 问题 算法