一.题目
分析:每次可以进行三次操作,求在n步操作后可以达到目标数的最小n,和最短路径问题相似,分层遍历加记忆化搜索防止时间复杂度过高,还需要减枝操作
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Scanner;public class Text10 {public static int sum = 0;public static void main(String[] args) {Scanner scan = new Scanner(System.in);long x = scan.nextLong();int k = scan.nextInt();Long n = x;System.out.println(bfs(n,k));scan.close();}public static int bfs(Long n,int k){Queue<Long> queue = new LinkedList<>();Set<Long> visted = new HashSet<>();//记录数组queue.add(n);//存入初始值Long res,tmp;while(!queue.isEmpty()){int cnt = queue.size();for(int i = 0;i<cnt;i++)//分层处理{res = queue.poll();if(res==k)return sum;if(res>k){queue.add(res - 1);if(res-1==k) return sum + 1;continue;}Long[] arr = {res + 1,res - 1,res * 2};for(Long x:arr){if(x==k) return sum + 1;if(k>0&&!visted.contains(x)){queue.add(x);visted.add(x);}}}sum++;//每一层sum+1}return -1;}
}
二.总结
bfs算法求最短路径问题时,需要记忆化搜搜
原因
1.迷宫:防止后来的路径覆盖最短路径
2.本题:防止重复计算已经计算过的路径,减少时间复杂度
本题需要大量减枝,因为每次操作变化小,这也是为什么不能用dfs的原因,dfs算法也可以求解,不过时间复杂度很高,递归太深入了,比如说1到10000会进行9999次递归,时间复杂度是指数级的
3.只有答案需要返回操作步骤数时才需要分层处理,比如求最短路径就不需要分层处理,只需要返回路径就可以,如果是需要知道走了几步,那就需要分层处理记录
三.错误总结
1.时间复杂度过高
没有减枝,当当前数大于k时,只需要-1操作就行,没有设置记忆数组,已经遍历过的结果不需要再次遍历,使用Hashset是因为它是哈希表结构,查询快效率高
2.没有思考清楚什么情况会返回-1
没有返回-1的情况,题目陷阱
3.返回值错误
eg:
在这里如果没有检查res就可能会发生错误
假如说在第n层res-1的结果等于k,那么res-1就存储在第85层,如果在这个位置前有一个值+1可以等于k那么返回来sum+1在86层,就导致结果错误,所以每次操作都需要立即检查,没检查就会导致多一层搜索