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

浙公网安备 33010602011771号