How can I generate 9 random numbers between 1 to 9,without repetition, one after another. Its like: Lets assume that the first random number generated is 4, then the next random number has to be in [1, 9] - {4}. My first approach was to add each randomly generated number to a set, and so avoid duplication. But then in worse cases, like we have already generated 6 and we have to generate 3 more numbers, the process goes a little slow. And when the range is changed from [1, 9] to [1, 1000], this approach doesn't sound correct. Can anyone suggest an alternative approach.
-
1You can swap the just-selected number with the one at the end, and pretend that on the next step you will be selecting from an array that is one element shorter. – j_random_hacker Jul 01 '14 at 11:08
-
generate a number and keep count of its `frequency`..if `frequency > 0` generate another random number and `add` or `subtract`or do some mathematical operation to obtain another number..although this will be also very hectic job – rock321987 Jul 01 '14 at 11:11
-
1You need to generate a permutation and select from the permutation. Shuffle if you can keep it all in memory – odedsh Jul 01 '14 at 11:14
-
generate array: int set[9]={1,2,3,4,5,6,7,8,9} and in a loop for(i=0;i<9;i++) swap set[i] and set[j] where j is random number < 0 , 8 > this is O(N) which is acceptable i think – Spektre Jul 01 '14 at 13:59
7 Answers
Start with a sorted array (trivialy easy to create by a for-loop); then shuffle bey swapping each array element with another (random chosen) element. To avoid the bias discussed in the comments, the index of the other element must be equal or higher than the index of the first element. If the indexes are equal, then the element is not swapped. (The original version of this answer contained a sentence about the possibility of the element being swapped back, but this is now obsolete since this can't happen anymore with the highlighted modification)

- 36,381
- 5
- 80
- 102
-
3In fact this seemingly correct algorithm [actually shuffles nonrandomly](http://blog.codinghorror.com/the-danger-of-naivete/). – j_random_hacker Jul 01 '14 at 11:17
-
3To get an unbiased shuffle, you need to make sure that you swap each element only with a randomly-chosen *later* element, or itself (i.e. no swap). – j_random_hacker Jul 01 '14 at 11:22
-
You're welcome :) It's not a big change, so if you update your answer I'll +2. – j_random_hacker Jul 01 '14 at 11:55
If you are not interested in implementing yourself an algorithm to do what you want, you can use a simply way, already implemented in the Java libraries.
You can create a collection (a sorted List
) of Integer
(start
to end
, where start=1
and end=9
in your example), and then use the method Collections.shuffle(list);
, for instance in this way:
static List<Integer> randArray(int start, int end) { //specify start/end
List<Integer> randList=new ArrayList<>(end-start+1); //create list
for (int k=start;k<=end;k++) { //generate integers in order
randList.add(k); //add integers to the list
}
Collections.shuffle(randList); //reoder randomly the list
return randList; //return the list with items in random order
}
The shuffle
method simply randomly reorder the items of the list.

- 2,598
- 1
- 13
- 26
-
yeah it works... although now i am more interested in knowing how does Collections.shuffle() work. – gonephishing Jul 01 '14 at 15:30
Following are two possible approaches :-
Method 1 :-
- Have all numbers in an array with size n.
- select a number an index at random i = rand(0,size)
- print arr[i]
- swap arr[i] and arr[size-1]
- size = size -1
- repeat 1 to 5 till list is exhausted.
Time Complexity: O(N)
Space Complexity: O(N)
Method 2:-
- Select a pool size of K.
- generate K random integers.
- show them as first k results.
- Add them to a hashset.
- Add all ak+1 for all previous integers in a pool.
- Add 1 if it is not in hashset.
- pick a integer r at random from pool and show it .
- Add r+1 into pool if its not in hashset
- Do 7 to 8 till pool is exhausted.
Time complexity: O(N)
Space complexity: O(K)
Pro & Cons :-
Method 1: Use this method for small integer ranges as it requires larger space but it is very fast and random.
Method 2: Use this method for larger ranges as it takes memory O(K) which is of your choice. The higher the k the higher is the randomness in the numbers generated. So you can achieve a nice trade off between space and randomness with maintaining good speed.

- 6,106
- 3
- 20
- 19
Create an ArrayList like that:
index 0->index 1->index 2...
[1] -> [2] -> [3]....
Generate a random index value betwen 0 and list.size() and get the position in list:
yourNumberResult = get(randomIndexValue).
Then remove the position in the list:
list.remove(randomIndexValue)
Then repeat this in iteration until list.size()==0

- 3,872
- 1
- 19
- 14
-
1Note that removing items from an ArrayList is inefficient, since all the items that follow the removed one have to be shifted down to fill the gap. Doing this repeatedly on a large array will cause a lot of memory traffic that may be a bottleneck. – Wyzard Jul 01 '14 at 11:18
-
i guess swapping instead of removing would be quicker, but yeah, thanks for the algorithm – gonephishing Jul 01 '14 at 12:03
-
I dont know because the swap algorithm is very complex. I think that for lists with < 10000 you dont have performance differences but, if it is important, try the two ways and count time. – João Marcos Jul 01 '14 at 13:15
Generate an array for numbers 1 to 9 in sorted order.
int arr[]=new int[9];
for(int i=0;i<9;i++)
arr[i]=i+1;
Now shuffle
the given array.
How to Shuffle an array?
To shuffle an array a of n elements (indices 0..n-1):
for i from n - 1 downto 1 do
j = random integer with 0 <= j <= i
exchange a[j] and a[i]
References

- 2,608
- 2
- 22
- 31
-
yes... just got this algorithm ->[Fisher-Yates_shuffle](http://en.wikipedia.org/wiki/Fisher-Yates_shuffle) – gonephishing Jul 01 '14 at 12:01
-
Yeah, this one will generate numbers from 1 to 9 in random fashion with equal probabilities. – Ayush Jul 01 '14 at 12:08
Using Java 8, the method of Enne could be written like this:
private static List<Integer> generateRandom( int low, int high )
{
List<Integer> range = IntStream.range( low, high ).boxed()
.collect( Collectors.toList() );
Collections.shuffle( range );
return range;
}

- 1
- 1

- 3,366
- 1
- 22
- 27
public ArrayList<Integer> getRandom(int numbers,int min_value, int max_value)
{
HashSet<Integer> list = new HashSet<>();
Random r = new Random();
while (list.size()<numbers) {
list.add(r.nextInt(max_value - min_value) + min_value);
}
return new ArrayList<>(list);
}
Alternative:
public ArrayList<Integer> getRandom(int numbers,int min_value, int max_value)
{
Random r = new Random();
ArrayList<Integer> list = new ArrayList<>();
for(int i=min_value; i<=max_value;i++)
list.add(i);
while (list.size()>numbers) {
list.remove(r.nextInt(list.size()));
}
Collections.shuffle(list);
return list;
}
Alternative:
public ArrayList<Integer> getRandom(int numbers, int min_value, int max_value) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = min_value; i <= max_value; i++) {
list.add(i);
}
Collections.shuffle(list);
return new ArrayList<>(list.subList(0, numbers));
}

- 4,825
- 4
- 24
- 43
-
thanks...all three algorithms work. Although as i have mentioned, in the first approach, list.add() will make the process slower as more and more numbers are filled in the HashSet coz same random numbers would be generated again and again. This effects the efficiency of the algorithm. Also, as mentioned in other comments, list.remove() method is inefficient as numbers have to be shifted every time you remove a number to fill the gap. I guess [Fisher-Yates_shuffle](http://en.wikipedia.org/wiki/Fisher-Yates_shuffle) is one algo that works similar to Collections.shuffle(). – gonephishing Jul 01 '14 at 15:24