You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

亚马逊面试DAG问题优化思路求教:遍历法存疑

突破DAG“最吵闹的人”面试题瓶颈的实用思路

嘿,太懂这种卡在亚马逊面试题上的挠头感了!你提到的用传递性遍历每个节点路径找终点、再比较筛选的思路方向是对的,但肯定是碰到效率或者逻辑上的瓶颈了对吧?我来给你捋捋可能的问题和优化方案:

你当前思路的核心瓶颈

  • 时间复杂度爆炸:如果DAG节点数稍多,比如超过20个,遍历所有路径的最坏时间复杂度会达到O(2^n),这在面试里绝对会被面试官追问优化方向——毕竟实际场景里没人能接受这么低效的解法。
  • 重复计算冗余:不同节点的路径大概率有大量重叠的子路径,你现在的方法应该是每次遍历都从头开始,完全没复用已经计算过的结果,这就导致做了很多无用功。

优化方案:拓扑排序+动态规划(DAG的黄金组合)

既然是有向无环图,拓扑排序是绕不开的高效工具,结合动态规划可以彻底解决重复计算的问题,把时间复杂度降到线性级别:

  1. 定义状态:给每个节点维护一个集合:
    • reachable_nodes[u]:节点u能到达的所有节点(如果“最吵闹的人”定义为能影响最多人
    • 要是题目定义是被最多人能影响,就改成维护reach_to[u]:所有能到达u的节点
  2. 拓扑序遍历
    • 先对DAG做拓扑排序,然后逆序遍历拓扑序列(计算reachable_nodes时):
      对于节点u,遍历它的所有邻接节点v,直接把reachable_nodes[v]的所有节点合并到reachable_nodes[u]里,再加上v本身——相当于直接复用后续节点的计算结果,不用再重复走路径。
  3. 筛选目标节点
    • 遍历所有节点的集合长度,找到长度最大的那个节点就是“最吵闹的人”。

举个直观例子

假设DAG是A → B → C,同时A → C

  • 拓扑序是A, B, C
  • 逆序遍历Creachable_nodes[C] = {C}
  • 遍历Breachable_nodes[B] = {B} ∪ reachable_nodes[C] = {B, C}
  • 遍历Areachable_nodes[A] = {A} ∪ reachable_nodes[B] ∪ reachable_nodes[C] = {A, B, C}
  • 此时A的可达节点最多,就是我们要找的“最吵闹的人”

简化代码思路

用Python写的伪代码大概是这样:

from collections import deque

def find_loudest_person(graph):
    # 第一步:生成拓扑序列
    in_degree = {node: 0 for node in graph}
    for u in graph:
        for v in graph[u]:
            in_degree[v] += 1
    
    queue = deque([node for node in in_degree if in_degree[node] == 0])
    topo_order = []
    while queue:
        current = queue.popleft()
        topo_order.append(current)
        for neighbor in graph[current]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)
    
    # 第二步:逆序拓扑序计算可达节点集合
    reachable = {node: {node} for node in graph}
    for node in reversed(topo_order):
        for neighbor in graph[node]:
            reachable[node].update(reachable[neighbor])
    
    # 第三步:找到可达节点最多的人
    loudest = max(graph.keys(), key=lambda x: len(reachable[x]))
    return loudest

这个解法的时间复杂度是O(V+E)(V是节点数,E是边数),比你之前的路径遍历高效太多,完全能应对面试里的测试用例。

内容的提问来源于stack exchange,提问作者Priyanka Sinha

火山引擎 最新活动