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