【问题标题】:Efficiently generating all possible permutations of a linked list?有效地生成链表的所有可能排列?
【发布时间】:2013-01-10 20:48:04
【问题描述】:

有许多算法可以生成一组给定值的所有可能排列。通常,这些值表示为具有 O(1) 随机访问权限的数组。

但是,假设要置换的元素表示为双向链表。在这种情况下,您无法在 O(1) 时间内随机访问列表中的元素,因此许多置换算法会出现不必要的减速。

是否有一种算法可以以尽可能少的时间和空间开销生成链表的所有可能排列?

【问题讨论】:

  • 事实上,生成所有排列的典型算法可以正常工作。
  • @izomorphius 因为链表访问是 O(n) 它可能会慢一些数量级。
  • 生成所有排列的算法具有 O(1) 的平均复杂度,而不是每个下一个排列调用。我会尝试添加一个答案。
  • 一个想法可能是创建一个指向链表节点的指针数组。花费 O(n) 时间。然后在该数组上使用置换算法会提高时间复杂度。
  • 从链表中创建一个数组作为预处理,然后对数组使用“黑盒”算法的开销可以忽略不计,考虑到生成所有可能排列的计算复杂度。

标签: algorithm data-structures linked-list complexity-theory permutation


【解决方案1】:

试着想一想如何在一张纸上生成所有排列。

您从最右边的数字开始,向左移动一个位置,直到看到一个小于其邻居的数字。然后将下一个值的数字放在那里,然后将所有剩余的数字按升序排列。这样做,直到没有更多事情可做。稍微考虑一下,您可以根据它们的数量在线性时间内对数字进行排序。

据我所知,这实际上是用于下一个排列的典型算法。我看不出为什么这在数组上会比在列表上更快。

【讨论】:

  • 您所描述的实现是否有学术/已知名称?
【解决方案2】:

您可能想查看Steinhaus–Johnson–Trotter algorithm。它仅通过交换相邻元素来生成序列的所有排列;您可以在 O(1) 中在双向链表中执行的操作。

【讨论】:

    【解决方案3】:

    您应该将链表的数据读入一个数组,该数组采用O(n),然后使用堆的排列 (http://www.geekviewpoint.com/java/numbers/permutation) 来查找所有排列。

    【讨论】:

      【解决方案4】:

      您可以使用Factoradic Permutation Algorithm,并相应地重新排列节点指针,以在不递归的情况下就地生成结果排列。

      伪描述:

      element_to_permute = list
      temp_list = new empty list
      for i = 1 in n! 
         indexes[] = factoradic(i)
         for j in indexes[]
            rearrange pointers of node `indexes[j]` of `element_to_permute` in `temp_list`
      

      【讨论】:

        猜你喜欢
        • 2012-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-18
        • 1970-01-01
        • 2016-02-16
        • 2016-09-09
        • 1970-01-01
        相关资源
        最近更新 更多