gpt4 book ai didi

java - 生成整数数组排列的最快方法

转载 作者:行者123 更新时间:2023-12-01 11:10:34 29 4
gpt4 key购买 nike

我想生成整数数组的所有不同排列。该数组可能包含重复项。但我想生成所有不同的排列。我尝试过下一个排列和递归方法,它们往往非常慢。请提出建议。

最佳答案

有n个! n 个元素的不同排列。生成单个排列的成本为 n(严格来说),因此任何排列生成算法的最小成本将为 O(n*n!)

Steinhaus–Johnson–Trotter 算法就是其中一种算法。有一些改进,例如 Shimon Even 的算法和其他算法(例如 Heap 的算法),但没有一个能在 O(n*n!) 下实现它们

谷歌搜索“排列算法”可以获得几种可以实现的不同算法,尽管大多数使用递归,这意味着另一个堆栈步骤。 Steinhaus–Johnson–Trotter 被定义为迭代,因此不应出现该问题。

这是一个 Java 实现

import java.util.Arrays;
import java.util.Iterator;

/**
* this implementation is based in Steinhaus–Johnson–Trotter algorithm and
* Shimon Even's improvement;
*
* @see https
* ://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm
*
*/
public class Permutations implements Iterator<int[]> {
/**
* direction[i] = -1 if the element i has to move to the left, +1 to the
* right, 0 if it does not need to move
*/
private int[] direction;
/**
* inversePermutation[i] is the position of element i in permutation; It's
* called inverse permutation because if p2 is the inverse permutation of
* p1, then p1 is the inverse permutation of p2
*/
private int[] inversePermutation;
/**
* current permutation
*/
private int[] permutation;

/**
* @param numElements
* >= 1
*/
public Permutations(int numElements) {
// initial permutation
permutation = new int[numElements];
for (int i = 0; i < numElements; i++) {
permutation[i] = i;
}
// the support elements
inversePermutation = Arrays.copyOf(permutation, numElements);
direction = new int[numElements];
Arrays.fill(direction, -1);
direction[0] = 0;
}

/**
* Swaps the elements in array at positions i1 and i2
*
* @param array
* @param i1
* @param i2
*/
private static void swap(int[] array, int i1, int i2) {
int temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}

/**
* prepares permutation to be the next one to return
*/
private void buildNextPermutation() {
// find the largest element with a nonzero direction, and swaps it in
// the indicated direction
int index = -1;
for (int i = 0; i < direction.length; i++) {
if (direction[permutation[i]] != 0
&& (index < 0 || permutation[index] < permutation[i])) {
index = i;
}
}
if (index < 0) {
// there are no more permutations
permutation = null;
} else {
// element we're moving
int chosenElement = permutation[index];
// direction we're moving
int dir = direction[chosenElement];
// index2 is the new position of chosenElement
int index2 = index + dir;

// we'll swap positions elements permutation[index] and
// permutation[index2] in permutation, to keep inversePermutation we
// have to swap inversePermutation's elements at index
// permutation[index] and permutation[index2]
swap(inversePermutation, permutation[index], permutation[index2]);
swap(permutation, index, index2);

// update directions
if (index2 == 0 || index2 == permutation.length - 1
|| permutation[index2 + dir] > permutation[index2]) {
// direction of chosen element
direction[chosenElement] = 0;
}

// all elements greater that chosenElement set its direction to +1
// if they're before index-1 or -1 if they're after
for (int i = chosenElement + 1; i < direction.length; i++) {
if (inversePermutation[i] > index2) {
direction[i] = -1;
} else {
direction[i] = 1;
}
}
}
}

@Override
public boolean hasNext() {
return permutation != null;
}

@Override
public int[] next() {
int[] result = Arrays.copyOf(permutation, permutation.length);
buildNextPermutation();
return result;
}
}

关于java - 生成整数数组排列的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32439571/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com