BFS
核心思想:把⼀些问题抽象成图,从⼀个点开始,向四周开始扩散。⼀般来说,我们写 BFS 算法都是⽤「队列」这种数据结构,每次将⼀个节点周围的所有节点加⼊队列。
常⻅场景:问题的本质就是让你在⼀幅「图」中找到从起点start 到终点 target 的最近距离。
BFS 相对 DFS 的最主要的区别是:BFS 找到的路径⼀定是最短的,但代价就是空间复杂度可能⽐ DFS ⼤很多。
773. 滑动谜题
解法:BFS
很经典的一个现实问题转化为BFS问题进行求解,具体求解思路可以参考益智游戏克星:BFS暴力搜索算法里的思路分析。
重点体会问题的转化、二维数组到一维字符串格式的转化,以及BFS求解过程中start和target条件的确定。
from queue import Queue
class Solution:
def slidingPuzzle(self, board: List[List[int]]) -> int:
# "123405"
neighbors = [
[1, 3],
[0, 2, 4],
[1, 5],
[0, 4],
[1, 3, 5],
start = ""
for i in range(len(board)):
for j in range(len(board[0])):
start += str(board[i][j])
target = "123450"
que = Queue()
que.put(start)
visited = set()
step = 0
while not que.empty():
size = que.qsize()
for _ in range(size):
node = que.get()
if node == target:
return step
if node in visited:
continue
visited.add(node)
i = node.index('0')
neigh_indexs = neighbors[i]
temp = list(node)
for j in neigh_indexs:
temp[i], temp[j] = temp[j], temp[i]
que.put("".join(temp))
temp[i], temp[j] = temp[j], temp[i]
step += 1
return -1
70. 爬楼梯
解法1:动态规划
分析发现找到了如下规律,f(x) = f(x-1) + f(x-2),类似斐波那契数列的推导过程,可以利用动态规划正向求解。
class Solution:
def climbStairs(self, n: int) -> int:
#斐波那契数列前两项;
a, b = 1, 1
#前三项Sn就是nn,所以从第4项开始计算,预设初始答案S3;
ans = 3
#小于3返回n;
if n <= 3:
return n
#从第4项开始计算,斐波那契数列求和;
for i in range(4, n + 1):
ans += a + b
a, b = b, a+b
return ans
解法2:递归
可以考虑逆递归+备忘录的方法解决,根据公式f(n) = f(n-1) + f(n-2)进行求解,备忘录是为了防止重复递归。
class Solution:
def climbStairs(self, n: int) -> int:
result = {}
def dfs(position):
if position == 1:
return 1
if position == 2:
return 2
if position not in result:
value = dfs(position-1) + dfs(position-2)
result[position] = value
else:
value = result[position]
return value
return dfs(n)