这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战
难度: 中等
题目描述
有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 toi 抵达 pricei。
现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1。
示例 1:
输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 1 输出: 200 解释: 城市航班图如下
从城市 0 到城市 2 在 1 站中转以内的最便宜价格是 200,如图中红色所示。
示例 2:
输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 0 输出: 500 解释: 城市航班图如下
从城市 0 到城市 2 在 0 站中转以内的最便宜价格是 500,如图中蓝色所示。
提示:
1 <= n <= 100 0 <= flights.length <= (n * (n - 1) / 2) flights[i].length == 3 0 <= fromi, toi < n fromi != toi 1 <= pricei <= 104 航班没有重复,且不存在自环 0 <= src, dst, k < n src != dst
解题思路
方法1:
DFS
这个其实就是回溯法,先从起点开始向后搜索,如果搜索到了 dst 或者没有步数了,那么换下一条路进行搜索。需要使用一个 seted 数组表示已经搜索过的节点,这样可以防止走成一个环。
class Solution(object):
def findCheapestPrice(self, n, flights, src, dst, K):
graps = collections.defaultdict(dict)
for u, v, e in flights:
graps[u][v] = e
seted = [0] * n
ans = [float('inf')]
self.dfs(graps, src, dst, K + 1, 0, seted, ans)
return -1 if ans[0] == float('inf') else ans[0]
def dfs(self, graph, src, dst, k, cost, seted, ans):
if src == dst:
ans[0] = cost
return
if k == 0:
return
for v, e in graph[src].items():
if seted[v]: continue
if cost + e > ans[0]: continue
seted[v] = 1
self.dfs(graph, v, dst, k - 1, cost + e, visited, ans)
seted[v] = 0
方法二:
BFS
如果给定步数的情况下,一个更直接的方法就是BFS,这样就可以直接判断在指定的k步以内能不能走到dst,不会进行更多的搜索了,因此这个方法要快很多。
class Solution(object):
def findCheapestPrice(self, n, flights, src, dst, K):
graps = collections.defaultdict(dict)
for u, v, e in flights:
graps[u][v] = e
ans = float('inf')
que = collections.deque()
que.append((src, 0))
step = 0
while que:
size = len(que)
for i in range(size):
cur, cost = que.popleft()
if cur == dst:
ans = min(ans, cost)
for v, w in graps[cur].items():
if cost + w > ans:
continue
que.append((v, cost + w))
if step > K: break
step += 1
return -1 if ans == float('inf') else ans