如何计算由多层有序对构成的连续有效路径数量?
高效解决跨层级连续路径计数问题
嘿,这个问题我太熟了!咱们来搞清楚怎么高效解决它——你之前想的哈希思路其实方向完全正确,只要结合动态规划优化一下,就能做到时间和空间都很高效,还完美适配你说的那种“生成有序对的函数每次仅返回一个子列表”的流式场景~
核心思路:动态规划+哈希表
我们不需要生成所有可能的路径(这会导致空间爆炸),而是只跟踪每个节点作为路径终点的累计数量。这样既能快速计算跨层级的有效衔接数,又能统计出符合要求的总路径数,全程不需要存储任何完整路径。
具体步骤
初始化第一个层级
- 用一个哈希表(比如Python的
dict)prev_counts记录第一个层级中,每个节点作为终点的路径数。每个有序对(u,v)对应一条到v的长度为1的路径,所以遍历第一个层级时,每遇到(u,v)就执行prev_counts[v] = prev_counts.get(v, 0) + 1。 - 总有效路径数
total初始化为0(单个层级的路径不算有效路径)。
- 用一个哈希表(比如Python的
遍历后续每个层级
- 对每个层级,创建新的哈希表
curr_counts,用来记录当前层级处理完后各节点的终点计数。 - 遍历当前层级的每个路径段
(x,y):- 先查
prev_counts中x的计数,这就是能和当前路径段衔接的上一层路径数量(记为connections)。 - 把
connections加到total里——这些就是新增的有效路径(长度≥2,符合连续路径规则)。 - 更新
curr_counts[y]:它等于当前已有的计数,加上connections(衔接后的路径数),再加上1(当前路径段自身作为一条长度为1的路径,供下一层级衔接使用)。
- 先查
- 处理完当前层级后,把
prev_counts替换为curr_counts,继续处理下一个层级。
- 对每个层级,创建新的哈希表
返回结果
遍历完所有层级后,total就是符合要求的有效路径总数。
示例验证(你的例子)
层级列表:[[(1,2), (3,3), (7,5)],[(2,3), (3,2), (6,4), (2,4)]]
- 处理第一个层级后:
prev_counts = {2:1, 3:1, 5:1},total=0 - 处理第二个层级:
(2,3):connections=1→total=1;curr_counts[3] = 1+1=2(3,2):connections=1→total=2;curr_counts[2] =1+1=2(6,4):connections=0→total不变;curr_counts[4] =0+1=1(2,4):connections=1→total=3;curr_counts[4] =1+1+1=3
- 最终
total=3,和你的预期完全一致!
代码实现(Python示例)
def count_valid_paths(layers): if len(layers) < 2: return 0 # 初始化第一个层级的终点计数 prev_counts = {} for u, v in layers[0]: prev_counts[v] = prev_counts.get(v, 0) + 1 total = 0 # 处理后续层级 for layer in layers[1:]: curr_counts = {} for x, y in layer: connections = prev_counts.get(x, 0) total += connections # 更新当前层级的终点计数:衔接的路径数 + 当前路径自身 curr_counts[y] = curr_counts.get(y, 0) + connections + 1 prev_counts = curr_counts return total # 测试你的示例 layers = [[(1,2), (3,3), (7,5)],[(2,3), (3,2), (6,4), (2,4)]] print(count_valid_paths(layers)) # 输出3
为什么这个方法高效?
- 时间复杂度:O(N),N是所有层级的有序对总数,每个有序对只处理一次。
- 空间复杂度:O(K),K是出现过的节点数量,远低于DFS生成所有路径的空间开销。
- 流式友好:每次只需要处理一个层级,处理完就可以丢弃,不需要把所有层级都加载到内存里,完美适配你提到的“生成有序对的函数每次仅返回一个子列表”的场景。
内容的提问来源于stack exchange,提问作者user13925866




