难度: Hard
Submission
运行时间: 263 ms
内存: 55.1 MB
class Solution: def chaseGame(self, edges: List[List[int]], sta: int, stb: int) -> int: n = len(edges) g = [[] for _ in range(n)] deg = [0] * n sta -= 1 stb -= 1 for u, v in edges: u -= 1 v -= 1 g[u].append(v) g[v].append(u) deg[u] += 1 deg[v] += 1 q = deque() for i in range(n): if deg[i] == 1: q.append(i) rest = n while q: u = q.popleft() rest -= 1 for v in g[u]: deg[v] -= 1 if deg[v] == 1: q.append(v) def bfs(st: int) -> List[int]: q = deque() q.append(st) dis = [inf] * n dis[st] = 0 while q: u = q.popleft() for v in g[u]: if dis[v] == inf: dis[v] = dis[u] + 1 q.append(v) return dis da = bfs(sta) db = bfs(stb) ans = 1 for i in range(n): if db[i] < da[i] - 1: if rest > 3 and deg[i] > 1: return -1 ans = max(ans, da[i]) return ans
Explain
该题解首先处理输入的边列表构建了一个无向图,并计算了每个节点的度。接着使用宽度优先搜索(BFS)来计算从起始点sta和stb到每个节点的最短距离。通过比较这两个距离数组,确定是否存在一个位置i使得小扣在小力之前到达且小力无法在下一步直接到达。如果存在这样的点,并且该点不是一个环路中的节点(即度大于1),则返回-1表示小力无法追上小扣。否则,计算小力追上小扣所需的最大距离,即为答案。
时间复杂度: O(n)
空间复杂度: O(n)
class Solution: def chaseGame(self, edges: List[List[int]], sta: int, stb: int) -> int: n = len(edges) g = [[] for _ in range(n)] # 邻接表表示图 deg = [0] * n # 节点的度 sta -= 1 # 转换为0-based索引 stb -= 1 for u, v in edges: u -= 1 v -= 1 g[u].append(v) g[v].append(u) deg[u] += 1 deg[v] += 1 q = deque() # 用于BFS for i in range(n): if deg[i] == 1: q.append(i) # 叶子节点加入队列 rest = n while q: # BFS处理所有节点 u = q.popleft() rest -= 1 for v in g[u]: deg[v] -= 1 if deg[v] == 1: q.append(v) def bfs(st: int) -> List[int]: q = deque() q.append(st) dis = [inf] * n dis[st] = 0 while q: u = q.popleft() for v in g[u]: if dis[v] == inf: dis[v] = dis[u] + 1 # 更新距离 q.append(v) return dis da = bfs(sta) # 从sta开始的距离数组 db = bfs(stb) # 从stb开始的距离数组 ans = 1 for i in range(n): if db[i] < da[i] - 1: if rest > 3 and deg[i] > 1: return -1 # 小扣可以逃脱 ans = max(ans, da[i]) # 更新所需最大回合数 return ans
Explore
在大多数图论问题中,尤其是在算法竞赛或在线编程平台如LeetCode中,题目通常会明确指出是否允许图中存在重复边或自环。通常,除非特别指示,我们假设输入的图不包含重复边和自环。如果题目允许这种情况发生,解题时必须对输入数据进行额外处理,比如使用集合来存储邻接点以避免重复边的影响,或者在添加边时检查是否形成自环。
宽度优先搜索(BFS)是确定无权图中从单一源点到其他所有点的最短路径的最优算法,因为它按层次遍历节点,确保当我们首次访问某节点时,我们已找到从起始点到该节点的最短路径。相比之下,深度优先搜索(DFS)可能会首先沿一条路径深入,不一定能直接找到最短路径。尽管其他算法如Dijkstra或Bellman-Ford也可用于找最短路径,但对于无权图来说,BFS更为简洁且效率更高。
在游戏逻辑中,度数为1的节点(即叶子节点)表示该节点仅与图中一个其他节点相连接。这在逃脱或追捕类游戏中非常关键,因为叶子节点本质上是图的边界,意味着从该节点只有一条路可走。这对策略制定非常重要,例如在追逐游戏中,如果追逐者(小力)追到一个叶子节点,且逃跑者(小扣)已经到达或即将到达那里,逃跑者的逃脱选择将非常有限。因此,叶子节点在确定追逐是否成功或是否存在潜在的逃脱路线时起着重要作用。