题目描述:
给你两个正整数 x
和 y
。
一次操作中,你可以执行以下四种操作之一:
- 如果
x
是11
的倍数,将x
除以11
。 - 如果
x
是5
的倍数,将x
除以5
。 - 将
x
减1
。 - 将
x
加1
。
请你返回让 x
和 y
相等的 最少 操作次数
解法一:BFS搜索
class Solution {
public:
int minimumOperationsToMakeEqual(int x, int y) {
if(x<=y){
return y-x;
}
int ans=x-y;
vector<int> vis(x+ans+1);
vector<int> q;
int step=0;
auto add=[&](int v){
if(v<y){
ans=min(ans,step+1+y-v);
}else if(!vis[v]){
vis[v]=true;
q.push_back(v);
}
};
add(x);
while(true){
auto tmp=q;
q.clear();
for(int v:tmp){
if(v==y){
return min(ans,step);
}
if(v%11==0){
add(v/11);
}
if(v%5==0){
add(v/5);
}
add(v-1);
add(v+1);
}
step++;
}
}
};
ans用来存储当前数据直接使用减法或者加法到达y数值的操作数,step用来记录利用除到达y的操作数。add()用来更新ans的同时把经过操作的数字添加到bfs队列当中。
解法二:记忆化搜索+BFS
class Solution {
unordered_map<int, int> memo;
public:
int minimumOperationsToMakeEqual(int x, int y) {
if (x <= y) {
return y - x;
}
auto it = memo.find(x);
if (it != memo.end()) {
return it->second;
}
return memo[x] = min({x - y,
minimumOperationsToMakeEqual(x / 11, y) + x % 11 + 1,
minimumOperationsToMakeEqual(x / 5, y) + x % 5 + 1,
minimumOperationsToMakeEqual(x/5+1,y)+5-x%5+1,
minimumOperationsToMakeEqual(x/11+1,y)+11-x%11+1
});
}
};
可以把x-->y转化为x'-->y其中x'的变化方案有,为x/11向下取整。x/11向上取整。。。
注意x/11向上取整可以分为先向下取整再向上+1,但是注意
1+x%11+1不一定小于11-x%11+1