广度搜索(BFS)、哈希、队列、数组 [5916]转化数字的最小运算数

// 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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值