根据题意, 数字 n 的三种可能转化方式: n -> n - 1 or n + 1 or n * n
因此, 可从n开始进行广度优先搜索, 记录当前数字 curNum 以及当前的操作步数 curStep, 并使用一个 set 记录已访问过的数字, 将curNum - 1, curNum + 1, curNum * curNum中未被访问的数字添加到搜索队列. 当curNum == m时搜索结束, 返回此时的操作步数, 即为所求的最少步数(因为步数是不断 +1 的, 可看作在所有边权值均为1的图上, 从n到m的最短距离)
[注] 由于n -> n + 1以及n -> n * n这两种转化方式的存在, n会越来越大甚至超过m, 因此需要进行一次"剪枝": n不超过m时, 才能进行上述转化.
# # 返回最后要输出的答案 # @param n int整型 表示牛牛的数字 # @param m int整型 表示牛妹的数字 # @return int整型 # class Solution: def solve(self , n , m ): que = [[n, 0]] seen = set(); seen.add(n) while que: curNum, curStep = que.pop(0) if curNum == m: return curStep if curNum - 1 not in seen: que.append([curNum - 1, curStep + 1]) seen.add(curNum - 1) if curNum <= m and (curNum + 1 not in seen): que.append([curNum + 1, curStep + 1]) seen.add(curNum + 1) if curNum <= m and (curNum * curNum not in seen): que.append([curNum * curNum, curStep + 1]) seen.add(curNum * curNum) return -1