algorithm - 生成序列排列的函数,元素限制为 1 个相邻移动

标签 algorithm sequence

假设有一个长度为 n 的列表,其中包含字母 A - char(n)。我想找到每个字母只能相邻移动或保持原位的排列。所以对于每个 seq,有三个“集合”排列,向左循环,向右循环(列表被认为是循环的),以及原始列表。我无法想出一种算法来处理列表中间可能发生的交换。主要是,要交换的字母配对如何跳过字母。 例如:列表的排列,其中 n = 3 [ABC、CAB、BCA、ACB、CBA、BAC] 此外,ABC 和 CAB 被认为是唯一的,尽管元素相对于彼此具有相同的位置。主要是寻找算法而不是任何特定的语言。 基本规则是元素最多可以远离其在列表中的原始位置 1 个位置。

最佳答案

我将勾勒出一个高效的枚举策略。

首先让我们解决没有回绕的更简单的问题。最左边的元素有两种可能性。它要么留在原地,要么向右移动。如果它向右移动,那么它所取代的元素必须向左移动。我们可以递归地枚举其余排列的可能性。

# this code is for the simpler problem, without wraparound
# the algorithm for the problem with wraparound is described in prose below

def perms_line(lst, j):
    if len(lst) - j < 2:
        print(lst)
    else:
        perms_line(lst, j + 1)
        lst[j], lst[j + 1] = lst[j + 1], lst[j]
        perms_line(lst, j + 2)
        lst[j], lst[j + 1] = lst[j + 1], lst[j]

perms_line([1, 2, 3, 4, 5], 0)

现在让我们考虑环绕。如果两个连续的元素向右移动,则每个元素都必须向右移动。如果两个连续的元素向左移动,则每个元素都必须向左移动。分别处理这些异常排列。

首先,考虑最左边的元素。它要么保持不变,要么与其右侧的元素交换,要么与最右边的元素交换。对于这三种可能性中的每一种(注意:如果 n = 2 则有两种,如果 n = 1 则只有一种),对排列的其余部分使用无环绕枚举策略。我将继续编写代码,因为需要一些操作才能正确完成。

关于algorithm - 生成序列排列的函数,元素限制为 1 个相邻移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26268564/

相关文章:

algorithm - 检查两个数学表达式是否等价

algorithm - 如何在层次结构中定位数据项位置?

c++ - 实现一个递归的Void函数(求二叉搜索树的高度)

java - 在网格上查找相交四边形的算法

python - 在线排序并删除两个整数流上的重复项

Python:根据两个特征的唯一组合和第三个特征的条件删除重复项

java - JPA 序列生成器

sequence - 水壶:用无冲突的顺序填充字段

SQL 生成序列号

uml - 注册和报告的序列图