2020.10.31 leetcode周赛总结

这是我第二次打周赛了,还是两道题gg,但是进步不少了,第三道题有非常明确的思路而且已经写出来了,只是有一个越界点没过最后没时间了,中途上了个厕所点了个外卖浪费了不少时间调试。相信一个半小时拉满是能解出来三道题的。另外这里第三道题因为不审题浪费了许多时间,特此总结

2059. 转化数字的最小运算数

https://leetcode-cn.com/problems/minimum-operations-to-convert-number/

这道题显然是搜索了,但是怎么去避免指数爆炸?看清楚条件就显得非常非常重要了!

一定要看清楚条件! num的范围只有0~1000!暗示你这道题的关键是记录好每一次的结果,不要重复操作!最多只需要对数操作1000次,根本不会指数爆炸!题目每一个在一定范围内的条件一定不可能是白给的,这种条件一定是有深意的,暗示你往某个方向去想!
我的思路是从goal开始反向操作,尝试操作回start

建立一个HashSet记录将要操作的数,TotalSet记录所有操作过的数,把goal放进去
清空操作数set
遍历将要操作的数,算出加,减,异或三个结果,判断这三个结果是否被操作过,如果没被操作过则放入Set中
不停循环,直到没有新数再加入Set

class Solution {
    boolean range(Long num) {
        return num >= 0 && num <= 1000;
    }

    public int minimumOperations(int[] nums, int start, int goal) {
        int[] record = new int[1000];
        Set<Long> totalSet = new HashSet<>();
        Set<Long> nextSet = new HashSet<>();
        // nextSet记录每次循环需要操作的数
        nextSet.add((long)goal);
        // totalSet记录操作过的数
        totalSet.add((long)goal);
        int count = 0;

        while (true) {
            count++;
            boolean newPut = false;
            Set<Long> tempSet = new HashSet<>();
            // 遍历将要操作的数进行操作,将数放入下一次要操作的数的Set中
            for (long num : nextSet) {
                for (int i = 0; i < nums.length; i++) {
                    //进行三种操作
                    long res1 = num + nums[i];
                    long res2 = num - nums[i];
                    long res3 = num ^ nums[i];
                    if (res1 == start) {
                        return count;
                    }
                    if (res2 == start) {
                        return count;
                    }
                    if (res3 == start) {
                        return count;
                    }
                    // 如果在范围内且没有被操作过,则放入集合
                    if (range(res1) && !totalSet.contains(res1)) {
                        newPut = true;
                        tempSet.add(res1);
                        totalSet.add(res1);

                    }
                    if (range(res2) && !totalSet.contains(res2)) {
                        newPut = true;
                        tempSet.add(res2);
                        totalSet.add(res2);
                    }
                    if (range(res3) && !totalSet.contains(res3)) {
                        newPut = true;
                        tempSet.add(res3);
                        totalSet.add(res3);
                    }
                }
            }
            // 没有新数加入了,说明无法转换成start
            if (!newPut) {
                return -1;
            }
            nextSet = tempSet;
        }
    }
}

  

原文地址:https://www.cnblogs.com/PanYuDi/p/15493538.html