// 5916. 转化数字的最小运算数
class Solution {
public int minimumOperations(int[] nums, int start, int goal) {
// 记录已经访问的中间运算结果
// 这里也可以使用一个数组去存储,大小为[1001]即可,每个下标对应中间的运算结果,默认值为0,当出现过将其设为1,也可以起到记录的作用
Set<Integer> visitedSet = new HashSet<>();
// 广度优先搜索(BFS)队列,这里主要存储当前已经达到的最大层的元素
Queue<Integer> bfsQueue = new ArrayDeque<>();
// 第一层默认为1个元素
bfsQueue.add(start);
// 记录访问
visitedSet.add(start);
// 这里使用 包装类 的原因是由于在集合中所有元素都是以它的包装类存在的,在后面加入队列时可以减少装箱操作,一定程度加快了处理速度
// 存放每次计算的答案
Integer opsAns = null;
// 这里使用 基础类型 的原因是在进行数字计算时需要使用基础类型,而不是对应的包装类, 在取出后需要进行加、减、异或等运算,这样可以减少拆箱操作 一定程度加快了处理速度
// 临时存储从队列中取出的队头元素
int val = 0;
// 存放最后的返回值,即计算的次数
int opsNum = 0;
// 遍历一直到队列中没有元素
while(!bfsQueue.isEmpty()){
// 记录运算次数
opsNum++;
// 当前层的元素数量(这里类似树的层序遍历,opsNum 即为层数)
int len = bfsQueue.size();
// 从队头获取所有当前层的元素
for(int i = 0; i < len; i++){
// 获取队头元素,并移除(这里会有拆箱操作:包装类 -> 基础类型)
val = bfsQueue.remove();
// 遍历可参与计算的数字
for(int j = 0; j < nums.length; j++){
// 加法计算
opsAns = val + nums[j];
// 如果为目标结果直接返回
if(goal == opsAns)
return opsNum;
// 计算结果在0到1000之间, 并且没有在visitedSet中出现过(这里也就是在深度遍历时,出现环的情况,表示这个分支遍历结束)
if(opsAns >= 0 && opsAns <= 1000 && !visitedSet.contains(opsAns)){
bfsQueue.add(opsAns);
visitedSet.add(opsAns);
}
// 减法计算
opsAns = val - nums[j];
if(goal == opsAns)
return opsNum;
if(opsAns >= 0 && opsAns <= 1000 && !visitedSet.contains(opsAns)){
bfsQueue.add(opsAns);
visitedSet.add(opsAns);
}
// 异或计算
opsAns = val ^ nums[j];
if(goal == opsAns)
return opsNum;
if(opsAns >= 0 && opsAns <= 1000 && !visitedSet.contains(opsAns)){
bfsQueue.add(opsAns);
visitedSet.add(opsAns);
}
}
}
}
// 未找到则直接返回-1
return -1;
}
}
广度搜索(BFS)、哈希、队列、数组 [5916]转化数字的最小运算数
最新推荐文章于 2024-09-27 00:45:01 发布