题目给出两个数a b,求由a经过加一,减一或乘二经过最小的步数n到b,输出n,例如:对于a=5,b=17 有:5-10-9-18-17, n=4.想到用树的BFS(广度优先遍历),建立一颗根为5的树,不断BFS,当出现17时结束即可。由于题目要求的数据很大,而且BFS过程中会出现很多重复的元素,所以过程中要不断剪枝,才能不至于超时。
在该实现中,建立了先进先出的队列来存储新生成的节点,每一个node包含一个值和一个深度depth,对节点的剪枝首先采取了一下方式:将出现过的节点放在一个ArrayList中,然后每一个node入队时判断是不是已经在ArrayList中了,如果在了就不加入了,当出现大量的需要剪枝的元素时,这种方式效率会很低,因为每次都要遍历存放处理过的元素的ArrayList,还是用惯用的“空间换时间”的方法,建立bool型flag[i]存放i是否已经在队列中出现过,如果出现过就剪枝,这样,每次判断元素是否出现过时间复杂度就由O(n)降到O(1)。另外:如果输入一大一小的数,有题意结果即为两数之差,这样的判断会很大程度上提高效率,时间由5391ms降到4141ms。
带有详细注释的代码可以从
http://download.csdn.net/user/china8848/
获得。