python - 选择适当的算法来创建和计算元素共享对的排列

标签 python algorithm time-complexity permutation graph-algorithm

我对执行以下任务的时间复杂度最低的算法感兴趣:

给定一个元组列表,例如 [(A, B), (B, C), (C, D), (D E), (A, D), (E, A), (A, C )], 查找诸如 [A, B, C, D, E, A] 或 [A, D, C, B, >A],它们以相同的字母开始和结束,并且通过连接共享元组中至少一个元素的对形成。注意:(A, B) 被认为与 (B, A) 相同,就像 (A, C) 与 (C, A) 相同,因此它可用于创建两个对 (C, B, A, C) 或 (A, B, C, A)

重要的约束是对长度有限制。例如。确保序列不超过 7 个元素。

我试图通过每次扩展树一个元素直到达到最大长度 7 来解决这个问题,但我很好奇是否有更好的方法来解决这个问题。非常感谢并期待听到您的好主意!

最佳答案

时间复杂度

解决此问题的任何算法的(最坏情况)时间复杂度的下限都是 O(n),其中 n 是边数 (即图的元组):

  • 如果您需要找到从 A 到 A 的所有个循环,您不能排除寻找某个边缘,因为它很可能是一个这样的循环的一部分。
  • 如果您需要找到从 A 到 A 的任何个循环,您可能会遇到只有一个这样的循环的情况,在最坏的情况下,您可能会发现最后一个边您访问的是结束循环的那个。

因此在任何一种情况下,您(可能)都需要至少查看每条边一次。

算法

本质上有两种策略:广度优先或深度优先搜索。两者的时间复杂度均为 O(n)

您似乎尝试过的算法是广度优先搜索。当您需要找到最短循环时,这是更好的选择,因为一旦找到循环(A-to-A),您就可以退出算法。

深度优先搜索也是一个可行的选择,当然是在对循环长度设置了限制的情况下。在这种情况下,空间 复杂度为O(m),其中m 是循环的最大长度。根据图形(它的大小、它的平均分支因子),这可能比广度优先搜索所需的 O(n) 空间便宜得多。

此外,广度优先搜索需要不断切换状态,而递归和回溯(深度优先搜索的特征)期间发生的转换通常更容易处理。

准备工作

无论您使用哪种策略,请确保首先为图创建一个高效的数据结构。

由一对数组组成的简单数据结构(如您的问题中所述)不够好。为了实现最佳时间复杂度,您需要构建一个邻接表(或类似的东西),以便您可以在恒定时间内找到一个节点的邻居(通过一个元组可达)。

关于python - 选择适当的算法来创建和计算元素共享对的排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58584329/

相关文章:

python - NLTK - 多标签分类

python - 怎么才能看到请求数据呢?

python - 字谜解决错误python

arrays - 最小化创建非递减数组成本的动态规划问题

algorithm - 是否有一种数据结构用于存储自然数的 2D 点,允许检查 O(1) 中是否存在?

algorithm - 在树中搜索列表的时间复杂度

Java编程任务效率

python - 持有期交易策略盈亏——解决rolling_apply瓶颈

python - 在 redhat 上安装 rpy

ruby - 在没有排序功能的情况下对数组中的字符串进行排序 - Ruby