Este é o método SDK que você está procurando Collections.shuffle (Arrays.asList (array));
Louis Hong
2
@ Louisie Não, isso não funciona. Isso criaria uma List<int[]>entrada contendo uma. Veja minha resposta para saber como usar isso Collections.shuffle().
Duncan Jones
2
Não é realmente uma resposta para a pergunta original, mas MathArrays.shuffle da biblioteca commons-math3 faz o trabalho.
Sandris
1
Isso não é suficiente para garantir uma resposta, mas lembro-me de um artigo muito interessante do livro "Graphics Gems", que falava sobre atravessar uma matriz em ordem pseudo-aleatória. Na minha opinião, é melhor do que ter que embaralhar os dados em primeiro lugar. A implementação C é encontrada aqui github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c
Usar Coleções para embaralhar uma matriz de tipos primitivos é um exagero ...
É simples o suficiente para implementar a função você mesmo, usando, por exemplo, o shuffle de Fisher – Yates :
import java.util.*;import java.util.concurrent.ThreadLocalRandom;classTest{publicstaticvoid main(String args[]){int[] solutionArray ={1,2,3,4,5,6,16,15,14,13,12,11};
shuffleArray(solutionArray);for(int i =0; i < solutionArray.length; i++){System.out.print(solutionArray[i]+" ");}System.out.println();}// Implementing Fisher–Yates shufflestaticvoid shuffleArray(int[] ar){// If running on Java 6 or older, use `new Random()` on RHS hereRandom rnd =ThreadLocalRandom.current();for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);// Simple swapint a = ar[index];
ar[index]= ar[i];
ar[i]= a;}}}
Nitpick extremamente trivial, mas você pode simplesmente usar em println()vez de println(""). Mais claro na intenção Eu acho que :)
Cowan
55
Seria muito melhor usar Collections.shuffle (Arrays.asList (array)); então, fazendo um baralhamento.
Louis Hong
21
@ Louisie Collections.shuffle(Arrays.asList(array))não funciona, porque Arrays.asList(array)retorna Collection<int[]>não Collection<Integer>como você pensava.
Adam Stelmaszczyk
15
@exhuma Porque se você tem uma matriz de milhares ou milhões de valores primitivos para classificar, agrupar cada um em um objeto apenas para fazer uma classificação é um pouco caro, tanto na memória quanto na CPU.
PhiLho
14
Este não é o embaralhamento de Fisher-Yates. Isso se chama shuffle de Durstenfeld . O shuffle original dos pescadores corre em O (n ^ 2), o que é extremamente lento.
Pacerier
164
Aqui está uma maneira simples de usar ArrayList:
List<Integer> solution =newArrayList<>();for(int i =1; i <=6; i++){
solution.add(i);}Collections.shuffle(solution);
Você pode simplesmenteCollectons.shuffle(Arrays.asList(solutionArray));
FindOutIslamNow 23/01
@ Timmos Você está errado. Arrays.asList envolve a matriz original e, assim, modificá-la modifica a matriz original. É por isso que você não pode adicionar ou remover, porque as matrizes são de tamanho fixo.
Nand
@ Não tenho certeza do que eu estava pensando, mas olhando para o código-fonte, de fato o método Arrays.asList cria um ArrayList apoiado pelo array especificado. Obrigado por apontar isso. Excluiu meu comentário anterior (não foi possível editá-lo).
Timmos
100
Aqui está uma função funcional e eficiente da matriz de embaralhamento Fisher-Yates:
privatestaticvoid shuffleArray(int[] array){int index;Random random =newRandom();for(int i = array.length -1; i >0; i--){
index = random.nextInt(i +1);if(index != i){
array[index]^= array[i];
array[i]^= array[index];
array[index]^= array[i];}}}
ou
privatestaticvoid shuffleArray(int[] array){int index, temp;Random random =newRandom();for(int i = array.length -1; i >0; i--){
index = random.nextInt(i +1);
temp = array[index];
array[index]= array[i];
array[i]= temp;}}
Votado até porque eu precisava de uma solução que não tinha a alta sobrecarga de criar uma coleção de Integer
mwk
2
A segunda implementação não tem o potencial de trocar com seu próprio índice? random.nextInt(int bound)é exclusivo, mas apresentá-lo i + 1como argumento permitiria indexe ipotencialmente seria o mesmo.
bmcentee148
21
@ bmcentee148 Trocar um elemento consigo mesmo é permitido em uma ordem aleatória. Não entender isso enfraqueceu o Enigma e ajudou a habilitar Alan Turing a quebrá-lo. en.wikipedia.org/wiki/…
Ellen Spertus
4
O xortruque é ótimo para trocar registros de CPU quando a CPU não possui instruções de troca e não há registros livres, mas para trocar elementos de matriz dentro de um loop, não vejo nenhum benefício. Para as variáveis locais temporárias, não há motivo para declará-las fora do loop.
Holger
1
É um pouco mais eficiente declarar a tempvariável fora do loop. O XORtruque deve ser mais rápido do que usar uma tempvariável, mas a única maneira de garantir que ele realize um teste de benchmark.
Dan Bray
25
A classe Collections possui um método eficiente para embaralhar, que pode ser copiado, para não depender dela:
/**
* Usage:
* int[] array = {1, 2, 3};
* Util.shuffle(array);
*/publicclassUtil{privatestaticRandom random;/**
* Code from method java.util.Collections.shuffle();
*/publicstaticvoid shuffle(int[] array){if(random ==null) random =newRandom();int count = array.length;for(int i = count; i >1; i--){
swap(array, i -1, random.nextInt(i));}}privatestaticvoid swap(int[] array,int i,int j){int temp = array[i];
array[i]= array[j];
array[j]= temp;}}
para não depender disso ? Eu preferiria depender disso, se isso fosse possível.
shmosel
@shmosel Então fique à vontade para usá-lo. Certifique-se de importar a classe necessária e de ter convertido a matriz em uma lista Arrays.asList. Você tem que converter a lista resultante para uma matriz, também
KitKat
Você não pode usar Arrays.asList()em uma matriz primitiva. E você não precisaria convertê-lo novamente, porque é apenas um invólucro.
shmosel
13
Olhe para a Collectionsclasse, especificamente shuffle(...).
Como você usa essa classe de coleções no Android? Você precisa fazer uma importação especial (CRTL SHIFT O não funciona) para usá-la?
Hubert
@Hubert deve fazer parte do pacote java.util . Faz parte da biblioteca padrão desde a v1.2.
MauganRa
3
Para tornar sua resposta mais independente, ela deve conter código de exemplo. IE:import java.util.Collections; shuffle(solutionArray);
Stevoisiak
10
Aqui está uma solução completa usando a Collections.shuffleabordagem:
publicstaticvoid shuffleArray(int[] array){List<Integer> list =newArrayList<>();for(int i : array){
list.add(i);}Collections.shuffle(list);for(int i =0; i < list.size(); i++){
array[i]= list.get(i);}}
Observe que ele sofre devido à incapacidade do Java de traduzir suavemente entre int[]e Integer[](e, portanto, int[]e List<Integer>).
Abaixo, há três implementações diferentes de um shuffle. Você só deve usar Collections.shuffle se estiver lidando com uma coleção. Não há necessidade de agrupar sua matriz em uma coleção apenas para classificá-la. Os métodos abaixo são muito simples de implementar.
Você não está cronometrando as mesmas coisas e cronometrando cada uma delas apenas uma vez (a ordem deles conta e você esquece a otimização do tempo de execução). Você deve chamar range, toArraye toPrimitiveantes de qualquer tempo, e fazer um loop para poder concluir qualquer coisa (pseudo-código: faça várias vezes {gerar lista, arr e iarr; lista de embaralhamento de tempo; arr embaralhamento de tempo; arr embaralhamento de tempo; iarr de embaralhamento de tempo}). Meu resultados: 1: list: 36017ns, arr: 28262ns, iarr: 23334ns. 100: list: 18445ns, arr: 19995ns, iarr: 18657ns. Isso apenas mostra que int [] é pré-otimizado (por código), mas eles são quase equivalentes à otimização de tempo de execução.
Syre
9
Usar ArrayList<Integer>pode ajudá-lo a resolver o problema de embaralhar sem aplicar muita lógica e consumir menos tempo. Aqui está o que eu sugiro:
ArrayList<Integer> x =newArrayList<Integer>();for(int i=1; i<=add.length(); i++){
x.add(i);}Collections.shuffle(x);
Não há nada específico do Java8 nesse código. Isso funciona desde o Java2. Bem, funcionaria, uma vez que você conserte a inconsistência entre o primeiro uso liste a referência repentina cardsList. Mas como você precisa criar o temporário list, que você omitiu, não há benefício sobre a Collections.shuffle(Arrays.asList(arr));abordagem mostrada várias vezes aqui. O que também funciona desde o Java2.
Holger
3
Aqui está uma versão genérica para matrizes:
import java.util.Random;publicclassShuffle<T>{privatefinalRandom rnd;publicShuffle(){
rnd =newRandom();}/**
* Fisher–Yates shuffle.
*/publicvoid shuffle(T[] ar){for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);
T a = ar[index];
ar[index]= ar[i];
ar[i]= a;}}}
Considerando que ArrayList é basicamente apenas uma matriz, pode ser aconselhável trabalhar com uma ArrayList em vez da matriz explícita e usar Collections.shuffle (). Os testes de desempenho, no entanto, não mostram nenhuma diferença significativa entre os itens acima e Collections.sort ():
Shuffe<Integer>.shuffle(...) performance:576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance:629400 shuffles per second
MathArrays.shuffle(int[]) performance:53062 shuffles per second
A implementação do Apache Commons MathArrays.shuffle é limitada a int [] e a penalidade de desempenho provavelmente se deve ao uso do gerador de números aleatórios.
Parece que você pode passar new JDKRandomGenerator()para MathArrays.shuffle. Gostaria de saber como isso afeta o desempenho?
Brandon
Na verdade ... parece que MathArrays#shuffletem uma alocação em seu núcleo loop: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizarro.
Brandon
3
Random rnd =newRandom();for(int i = ar.length -1; i >0; i--){int index = rnd.nextInt(i +1);// Simple swapint a = ar[index];
ar[index]= ar[i];
ar[i]= a;}
A propósito, notei que esse código retorna ar.length - 1vários elementos; portanto, se sua matriz tiver 5 elementos, a nova matriz aleatória terá 4 elementos. Isso acontece porque o loop for diz i>0. Se você mudar para i>=0, todos os elementos serão embaralhados.
Apenas um aviso, você pode mover isso para a seção de comentários da sua pergunta, pois ela provavelmente será sinalizada se for deixada como sua própria resposta.
Jason D
1
Este parece responder à pergunta, então eu tenho certeza que você está falando sobre @JasonD
Sumurai8
1
O código está correto, o comentário está errado. Se você mudar i>0para i>=0, você perde tempo trocando o elemento 0consigo mesmo.
Jcsahnwaldt Restabelecer Monica
3
Aqui está uma solução usando o Apache Commons Math 3.x (apenas para matrizes int []):
Eu vi algumas informações de falta em algumas respostas, então decidi adicionar uma nova.
Java coleções Arrays.asList leva var-arg do tipo T (T ...). Se você passar uma matriz primitiva (matriz int), o método asList inferirá e gerará a List<int[]>, que é uma lista de um elemento (o elemento único é a matriz primitiva). se você embaralhar esta lista de um elemento, ela não mudará nada.
Portanto, primeiro você precisa converter sua matriz primitiva em matriz de objetos Wrapper. para isso, você pode usar o ArrayUtils.toObjectmétodo apache.commons.lang. depois passe a matriz gerada para uma lista e, finalmente, embaralhe-a.
int[] intArr ={1,2,3};List<Integer> integerList =Arrays.asList(ArrayUtils.toObject(array));Collections.shuffle(integerList);//now! elements in integerList are shuffled!
publicList<Integer> shuffleArray(List<Integer> a){List<Integer> b =newArrayList<Integer>();while(a.size()!=0){int arrayIndex =(int)(Math.random()*(a.size()));
b.add(a.get(arrayIndex));
a.remove(a.get(arrayIndex));}return b;}
Escolha um número aleatório da lista original e salve-o em outra lista.Em seguida, remova o número da lista original.O tamanho da lista original continuará diminuindo em um até que todos os elementos sejam movidos para a nova lista.
Estou avaliando essa questão muito popular porque ninguém escreveu uma versão aleatória. O estilo é muito emprestado Arrays.java, porque quem não está pilhando a tecnologia Java atualmente? Genérico e intimplementações incluídas.
/**
* Shuffles elements from {@code original} into a newly created array.
*
* @param original the original array
* @return the new, shuffled array
* @throws NullPointerException if {@code original == null}
*/@SuppressWarnings("unchecked")publicstatic<T> T[] shuffledCopy(T[] original){int originalLength = original.length;// For exception priority compatibility.Random random =newRandom();
T[] result =(T[])Array.newInstance(original.getClass().getComponentType(), originalLength);for(int i =0; i < originalLength; i++){int j = random.nextInt(i+1);
result[i]= result[j];
result[j]= original[i];}return result;}/**
* Shuffles elements from {@code original} into a newly created array.
*
* @param original the original array
* @return the new, shuffled array
* @throws NullPointerException if {@code original == null}
*/publicstaticint[] shuffledCopy(int[] original){int originalLength = original.length;Random random =newRandom();int[] result =newint[originalLength];for(int i =0; i < originalLength; i++){int j = random.nextInt(i+1);
result[i]= result[j];
result[j]= original[i];}return result;}
publicclassKnuth{// this class should not be instantiatedprivateKnuth(){}/**
* Rearranges an array of objects in uniformly random order
* (under the assumption that <tt>Math.random()</tt> generates independent
* and uniformly distributed numbers between 0 and 1).
* @param a the array to be shuffled
*/publicstaticvoid shuffle(Object[] a){int n = a.length;for(int i =0; i < n; i++){// choose index uniformly in [i, n-1]int r = i +(int)(Math.random()*(n - i));Object swap = a[r];
a[r]= a[i];
a[i]= swap;}}/**
* Reads in a sequence of strings from standard input, shuffles
* them, and prints out the results.
*/publicstaticvoid main(String[] args){// read in the dataString[] a =StdIn.readAllStrings();// shuffle the arrayKnuth.shuffle(a);// print results.for(int i =0; i < a.length; i++)StdOut.println(a[i]);}}
A solução mais simples para este embaralhamento aleatório em uma matriz.
String location[]={"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};int index;String temp;Random random =newRandom();for(int i=1;i<location.length;i++){
index = random.nextInt(i+1);
temp = location[index];
location[index]= location[i];
location[i]= temp;System.out.println("Location Based On Random Values :"+location[i]);}
publicstaticvoid randomizeArray(int[] arr){Random rGenerator =newRandom();// Create an instance of the random class for(int i =0; i< arr.length;i++){//Swap the positions...int rPosition = rGenerator.nextInt(arr.length);// Generates an integer within the range (Any number from 0 - arr.length)int temp = arr[i];// variable temp saves the value of the current array index;
arr[i]= arr[rPosition];// array at the current position (i) get the value of the random generated
arr[rPosition]= temp;// the array at the position of random generated gets the value of temp}for(int i =0; i<arr.length; i++){System.out.print(arr[i]);//Prints out the array}}
Adicione uma descrição relacionada à sua resposta.
Ankit suthar
0
import java.util.ArrayList;import java.util.Random;publicclass shuffle {publicstaticvoid main(String[] args){int a[]={1,2,3,4,5,6,7,8,9};ArrayList b =newArrayList();int i=0,q=0;Random rand =newRandom();while(a.length!=b.size()){int l = rand.nextInt(a.length);//this is one option to that but has a flaw on 0// if(a[l] !=0)// {// b.add(a[l]);// a[l]=0;// // }// // this works for every no. if(!(b.contains(a[l]))){
b.add(a[l]);}}// for (int j = 0; j <b.size(); j++) {// System.out.println(b.get(j));// // }System.out.println(b);}}
Random r =newRandom();int n = solutionArray.length;List<Integer> arr =Arrays.stream(solutionArray).boxed().collect(Collectors.toList());for(int i =0; i < n-1; i++){
solutionArray[i]= arr.remove( r.nextInt(arr.size()));// randomize base on size}
solutionArray[n-1]= arr.get(0);
Uma das soluções é usar a permutação para pré-calcular todas as permutações e armazenadas no ArrayList
O Java 8 introduziu um novo método, ints (), na classe java.util.Random. O método ints () retorna um fluxo ilimitado de valores int pseudo-aleatórios. Você pode limitar os números aleatórios entre um intervalo especificado, fornecendo os valores mínimo e máximo.
Random genRandom =newRandom();int num = genRandom.nextInt(arr.length);
Com a ajuda da geração do número aleatório, você pode percorrer o loop e trocar com o índice atual pelo número aleatório. É assim que você pode gerar um número aleatório com complexidade de espaço O (1).
List<int[]>
entrada contendo uma. Veja minha resposta para saber como usar issoCollections.shuffle()
.Respostas:
Usar Coleções para embaralhar uma matriz de tipos primitivos é um exagero ...
É simples o suficiente para implementar a função você mesmo, usando, por exemplo, o shuffle de Fisher – Yates :
fonte
println()
vez deprintln("")
. Mais claro na intenção Eu acho que :)Collections.shuffle(Arrays.asList(array))
não funciona, porqueArrays.asList(array)
retornaCollection<int[]>
nãoCollection<Integer>
como você pensava.Aqui está uma maneira simples de usar
ArrayList
:fonte
Collectons.shuffle(Arrays.asList(solutionArray));
Aqui está uma função funcional e eficiente da matriz de embaralhamento Fisher-Yates:
ou
fonte
random.nextInt(int bound)
é exclusivo, mas apresentá-loi + 1
como argumento permitiriaindex
ei
potencialmente seria o mesmo.xor
truque é ótimo para trocar registros de CPU quando a CPU não possui instruções de troca e não há registros livres, mas para trocar elementos de matriz dentro de um loop, não vejo nenhum benefício. Para as variáveis locais temporárias, não há motivo para declará-las fora do loop.temp
variável fora do loop. OXOR
truque deve ser mais rápido do que usar umatemp
variável, mas a única maneira de garantir que ele realize um teste de benchmark.A classe Collections possui um método eficiente para embaralhar, que pode ser copiado, para não depender dela:
fonte
Arrays.asList
. Você tem que converter a lista resultante para uma matriz, tambémArrays.asList()
em uma matriz primitiva. E você não precisaria convertê-lo novamente, porque é apenas um invólucro.Olhe para a
Collections
classe, especificamenteshuffle(...)
.fonte
java.util
. Faz parte da biblioteca padrão desde a v1.2.import java.util.Collections; shuffle(solutionArray);
Aqui está uma solução completa usando a
Collections.shuffle
abordagem:Observe que ele sofre devido à incapacidade do Java de traduzir suavemente entre
int[]
eInteger[]
(e, portanto,int[]
eList<Integer>
).fonte
Você tem algumas opções aqui. Uma lista é um pouco diferente de uma matriz quando se trata de embaralhar.
Como você pode ver abaixo, uma matriz é mais rápida que uma lista e uma matriz primitiva é mais rápida que uma matriz de objetos.
Durações da amostra
Abaixo, há três implementações diferentes de um shuffle. Você só deve usar Collections.shuffle se estiver lidando com uma coleção. Não há necessidade de agrupar sua matriz em uma coleção apenas para classificá-la. Os métodos abaixo são muito simples de implementar.
Classe ShuffleUtil
Método principal
Baralhar uma lista genérica
Baralhar uma matriz genérica
Baralhar uma matriz primitiva
Métodos de utilidade
Métodos utilitários simples para copiar e converter matrizes em listas e vice-versa.
Classe de alcance
Gera um intervalo de valores, semelhante à
range
função do Python .fonte
range
,toArray
etoPrimitive
antes de qualquer tempo, e fazer um loop para poder concluir qualquer coisa (pseudo-código: faça várias vezes {gerar lista, arr e iarr; lista de embaralhamento de tempo; arr embaralhamento de tempo; arr embaralhamento de tempo; iarr de embaralhamento de tempo}). Meu resultados: 1:list: 36017ns, arr: 28262ns, iarr: 23334ns
. 100:list: 18445ns, arr: 19995ns, iarr: 18657ns
. Isso apenas mostra que int [] é pré-otimizado (por código), mas eles são quase equivalentes à otimização de tempo de execução.Usar
ArrayList<Integer>
pode ajudá-lo a resolver o problema de embaralhar sem aplicar muita lógica e consumir menos tempo. Aqui está o que eu sugiro:fonte
O código a seguir obterá uma ordem aleatória na matriz.
from: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/
fonte
Você pode usar o java 8 agora:
fonte
list
e a referência repentinacardsList
. Mas como você precisa criar o temporáriolist
, que você omitiu, não há benefício sobre aCollections.shuffle(Arrays.asList(arr));
abordagem mostrada várias vezes aqui. O que também funciona desde o Java2.Aqui está uma versão genérica para matrizes:
Considerando que ArrayList é basicamente apenas uma matriz, pode ser aconselhável trabalhar com uma ArrayList em vez da matriz explícita e usar Collections.shuffle (). Os testes de desempenho, no entanto, não mostram nenhuma diferença significativa entre os itens acima e Collections.sort ():
A implementação do Apache Commons MathArrays.shuffle é limitada a int [] e a penalidade de desempenho provavelmente se deve ao uso do gerador de números aleatórios.
fonte
new JDKRandomGenerator()
paraMathArrays.shuffle
. Gostaria de saber como isso afeta o desempenho?MathArrays#shuffle
tem uma alocação em seu núcleo loop:int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();
. Bizarro.A propósito, notei que esse código retorna
ar.length - 1
vários elementos; portanto, se sua matriz tiver 5 elementos, a nova matriz aleatória terá 4 elementos. Isso acontece porque o loop for dizi>0
. Se você mudar parai>=0
, todos os elementos serão embaralhados.fonte
i>0
parai>=0
, você perde tempo trocando o elemento0
consigo mesmo.Aqui está uma solução usando o Apache Commons Math 3.x (apenas para matrizes int []):
http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle (int [])
Como alternativa, o Apache Commons Lang 3.6 introduziu novos métodos de shuffle na
ArrayUtils
classe (para objetos e qualquer tipo primitivo).http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-
fonte
Eu vi algumas informações de falta em algumas respostas, então decidi adicionar uma nova.
Java coleções Arrays.asList leva var-arg do tipo T
(T ...)
. Se você passar uma matriz primitiva (matriz int), o método asList inferirá e gerará aList<int[]>
, que é uma lista de um elemento (o elemento único é a matriz primitiva). se você embaralhar esta lista de um elemento, ela não mudará nada.Portanto, primeiro você precisa converter sua matriz primitiva em matriz de objetos Wrapper. para isso, você pode usar o
ArrayUtils.toObject
método apache.commons.lang. depois passe a matriz gerada para uma lista e, finalmente, embaralhe-a.fonte
Aqui está outra maneira de embaralhar uma lista
Escolha um número aleatório da lista original e salve-o em outra lista.Em seguida, remova o número da lista original.O tamanho da lista original continuará diminuindo em um até que todos os elementos sejam movidos para a nova lista.
fonte
Uma solução simples para Groovy:
Isso classificará todos os elementos da lista de matrizes aleatoriamente, arquivando o resultado desejado ao embaralhar todos os elementos.
fonte
Usando o Goiaba
Ints.asList()
é tão simples quanto:fonte
Estou avaliando essa questão muito popular porque ninguém escreveu uma versão aleatória. O estilo é muito emprestado
Arrays.java
, porque quem não está pilhando a tecnologia Java atualmente? Genérico eint
implementações incluídas.fonte
Esse é o algoritmo de shuffle knuth.
fonte
Existe outra maneira também, ainda não postar
assim, mais fácil, dependia do contexto
fonte
A solução mais simples para este embaralhamento aleatório em uma matriz.
fonte
int[]
atéInteger[]
Arrays.asList
métodoAleatório com o
Collections.shuffle
métodofonte
Código mais simples para embaralhar:
fonte
Usando a classe aleatória
fonte
fonte
fonte
semelhante sem usar swap b
fonte
Uma das soluções é usar a permutação para pré-calcular todas as permutações e armazenadas no ArrayList
O Java 8 introduziu um novo método, ints (), na classe java.util.Random. O método ints () retorna um fluxo ilimitado de valores int pseudo-aleatórios. Você pode limitar os números aleatórios entre um intervalo especificado, fornecendo os valores mínimo e máximo.
Com a ajuda da geração do número aleatório, você pode percorrer o loop e trocar com o índice atual pelo número aleatório. É assim que você pode gerar um número aleatório com complexidade de espaço O (1).
fonte
Sem solução aleatória:
fonte