N的迭代算法选择K,无重复,顺序重要

如何解决N的迭代算法选择K,无重复,顺序重要

我正在寻找一种迭代算法,以获取从一组N个元素中提取的K个元素的所有排列,而无需重复(即,不进行替换),并且其顺序很重要。 我知道排列的数量必须为N!/(N-K)!。 你有什么想法吗? 谢谢。

伊万

解决方法

方法1:

简单的想法:

由于顺序很重要,因此我们将尝试使用next_permutation algorithmnext_permutation函数可提供下一个字典上唯一的排列。

算法

  1. 创建一个新数组A,其大小等于原始数组的大小。
  2. 分配最后k个数字1,2,3,.. k,以使k结尾。将其余数字分配为0。
  3. 现在,当使用next_permutation遍历排列时,仅选择原始数组中的索引,其中A的值大于0,保持顺序。

正确性说明:

由于在新创建的数组中有N个数字,其中N-k个重复,因此唯一的总排列变为N!/(N-k)!这给了我们想要的结果。

示例:

输入:X = [1,3],k = 2

现在,我们创建A = [0,1,2]。

所有排列:

[0,2],[0,1],[1,0],[2,0].

仅从原始数组中选择这些排列的索引 i ,其中A [i]> 0,将产生

[2,3],[3,1].

如果要按排序的顺序在上方使用,请使用负数,并使用-k,-k-1,..- 1初始化前k个数字,然后使用0初始化剩余的k个数字,并稍加修改即可应用该算法,方法是在原始数组中选择索引 i ,以便A [i]

旁注: 如果顺序无关紧要,请使用A -1s初始化k,并在0之前保持-1s,然后使用迭代置换算法,该算法将从N个项目中产生唯一的k个选择。

方法2 :(优于方法1)

算法:

  1. 首先选择前K个数字,然后填充到数组A中,它将存储原始数组中所选元素的索引。我们将其标记为首选。
  2. 现在按字典顺序获得所有剩余的排列。
  3. 如何获得考虑订单的下一个组合?如果可能,我们将对选择进行置换,否则按字典顺序返回更大的选择。

如果排列已用尽,则按字典顺序获得下一个选择的想法:

考虑当前的组合,找到最右边的元素 尚未达到可能的最高价值。一旦找到这个 元素,我们将其加1,然后将最低有效值分配给 所有后续元素。

来自:https://cp-algorithms.com/combinatorics/generating_combinations.html

示例:

输入:X = [1,3,4],k = 3

现在,我们创建A = [0,2] // initialization [0,1] // next permutation ... // all permutations of [0,2] ... [2,0] // reached last permutation of current selection [0,3] // get next selection in lexicographic order as permutations are exhausted ... [3,0] // reached last permutation of current selection [0,0] // reached last permutation of current selection [1,1] // reached last permutation of current selection

代码(基于0的索引,因此从0-k-1初始化开始):

bool next_combination_with_order(vector<int>& a,int n,bool order_matters=true) {
    int k = (int)a.size();
    if(order_matters && std::next_permutation(a.begin(),a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
    // if `a` was already in descending order,// next_permutation returned false and changed the array to sorted order.
    // now find next combination if possible
    for (int i = k - 1; i >= 0; i--) {
        if (a[i] < n - k + i + 1) {
            a[i]++;
            for (int j = i + 1; j < k; j++)
                a[j] = a[j - 1] + 1;
            return true;
        }
    }
    return false;
}

参考:

下一个排列:

https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order

std::next_permutation Implementation Explanation

下一个无顺序组合:

https://cp-algorithms.com/combinatorics/generating_combinations.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?