Open In App

Generate a random permutation of 1 to N

Given an integer N, the task is to generate N non-repeating random numbers.

Examples:  



Input: N = 5 
Output: 1 5 2 4 3

Input: N = 8 
Output: 7 2 1 8 3 6 4 5 



Approach:  

Create an array of N elements and initialize the elements as 1, 2, 3, 4, …, N then shuffle the array elements using Fisher-Yates shuffle Algorithm.

Fisher–Yates shuffle Algorithm works in O(n) time complexity. The assumption here is, we are given a function rand() that generates a random number in O(1) time. 

The idea is to start from the last element, swap it with a randomly selected element from the whole array (including last). Now consider the array from 0 to n-2 (size reduced by 1), and repeat the process till we hit the first element. 

Below is the implementation of the above approach:  




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the next random number
int getNum(vector<int>& v)
{
 
    // Size of the vector
    int n = v.size();
 
    // Generate a random number
    srand(time(NULL));
 
    // Make sure the number is within
    // the index range
    int index = rand() % n;
 
    // Get random number from the vector
    int num = v[index];
 
    // Remove the number from the vector
    swap(v[index], v[n - 1]);
    v.pop_back();
 
    // Return the removed number
    return num;
}
 
// Function to generate n non-repeating random numbers
void generateRandom(int n)
{
    vector<int> v(n);
 
    // Fill the vector with the values
    // 1, 2, 3, ..., n
    for (int i = 0; i < n; i++)
        v[i] = i + 1;
 
    // While vector has elements
    // get a random number from the vector and print it
    while (v.size()) {
        cout << getNum(v) << " ";
    }
}
 
// Driver code
int main()
{
    int n = 8;
    generateRandom(n);
 
    return 0;
}




// Java implementation of the approach
import java.util.*;
import java.lang.Math;
 
class GfG
{
 
    // Function to return the next random number
    static int getNum(ArrayList<Integer> v)
    {
        // Size of the vector
        int n = v.size();
     
        // Make sure the number is within
        // the index range
        int index = (int)(Math.random() * n);
     
        // Get random number from the vector
        int num = v.get(index);
     
        // Remove the number from the vector
        v.set(index, v.get(n - 1));
        v.remove(n - 1);
     
        // Return the removed number
        return num;
    }
     
    // Function to generate n
    // non-repeating random numbers
    static void generateRandom(int n)
    {
        ArrayList<Integer> v = new ArrayList<>(n);
     
        // Fill the vector with the values
        // 1, 2, 3, ..., n
        for (int i = 0; i < n; i++)
            v.add(i + 1);
     
        // While vector has elements
        // get a random number from the vector and print it
        while (v.size() > 0)
        {
            System.out.print(getNum(v) + " ");
        }
    }
 
    // Driver code
    public static void main(String []args)
    {
         
        int n = 8;
        generateRandom(n);
    }
}
 
// This code is contributed by Rituraj Jain




# Python3 implementation of the approach
 
# import random module
import random
 
# Function to return the next
# random number
def getNum(v) :
 
    # Size of the vector
    n = len(v)
 
    # Generate a random number within
    # the index range
    index = random.randint(0, n - 1)
 
    # Get random number from the vector
    num = v[index]
 
    # Remove the number from the vector
    v[index], v[n - 1] = v[n - 1], v[index]
    v.pop()
 
    # Return the removed number
    return num
 
# Function to generate n non-repeating
# random numbers
def generateRandom(n) :
     
    v = [0] * n
 
    # Fill the vector with the values
    # 1, 2, 3, ..., n
    for i in range(n) :
        v[i] = i + 1
 
    # While vector has elements get a 
    # random number from the vector
    # and print it
    while (len(v)) :
        print(getNum(v), end = " ")
 
# Driver code
if __name__ == "__main__" :
     
    n = 8
    generateRandom(n)
     
# This code is contributed by Ryuga




// C# implementation of the approach
using System;
using System.Collections;
 
class GfG{
  
// Function to return the next random number
static int getNum(ArrayList v)
{
     
    // Size of the vector
    int n = v.Count;
     
    Random rand = new Random();
     
    // Make sure the number is within
    // the index range
    int index = (rand.Next() % n);
  
    // Get random number from the vector
    int num = (int)v[index];
  
    // Remove the number from the vector
    v[index] = (int)v[n - 1];
    v.Remove(v[n - 1]);
  
    // Return the removed number
    return num;
}
  
// Function to generate n
// non-repeating random numbers
static void generateRandom(int n)
{
    ArrayList v = new ArrayList(n);
     
    // Fill the vector with the values
    // 1, 2, 3, ..., n
    for(int i = 0; i < n; i++)
        v.Add(i + 1);
  
    // While vector has elements get a
    // random number from the vector
    // and print it
    while (v.Count > 0)
    {
        Console.Write(getNum(v) + " ");
    }
}
 
// Driver code
public static void Main(string []args)
{
    int n = 8;
     
    generateRandom(n);
}
}
 
// This code is contributed by rutvik_56




<?php
// PHP implementation of the approach
 
// Function to return the next random number
function getNum(&$v)
{
 
    // Size of the vector
    $n = sizeof($v);
 
    // Generate a random number
    srand(time(NULL));
 
    // Make sure the number is within
    // the index range
    $index = rand() % $n;
 
    // Get random number from the vector
    $num = $v[$index];
 
    // Remove the number from the vector
    $t = $v[$index];
    $v[$index] = $v[$n - 1];
    $v[$n - 1] = $t;
    array_pop($v);
 
    // Return the removed number
    return $num;
}
 
// Function to generate n non-repeating
// random numbers
function generateRandom($n)
{
    $v = array(0, $n, NULL);
 
    // Fill the vector with the values
    // 1, 2, 3, ..., n
    for ($i = 0; $i < $n; $i++)
        $v[$i] = $i + 1;
 
    // While vector has elements
    // get a random number from the
    // vector and print it
    while (sizeof($v))
    {
        echo getNum($v) . " ";
    }
}
 
// Driver code
$n = 8;
generateRandom($n);
 
// This code is contributed by ita_c
?>




<script>
// Javascript implementation of the approach
 
// Function to return the next random number
function getNum(v)
{
        // Size of the vector
        let n = v.length;
      
        // Make sure the number is within
        // the index range
        let index = Math.floor(Math.random() % n);
          
        // Get random number from the vector
        let num = v[index];
      
        // Remove the number from the vector
        v[index] = v[n - 1];
        v.splice(n - 1,1);
      
        // Return the removed number
        return num;
}
 
// Function to generate n
// non-repeating random numbers
function generateRandom(n)
{
        let v = [];
      
        // Fill the vector with the values
        // 1, 2, 3, ..., n
        for (let i = 0; i < n; i++)
            v.push(i + 1);
      
        // While vector has elements
        // get a random number from the vector and print it
        while (v.length > 0)
        {
            document.write(getNum(v) + " ");
        }
}
 
// Driver code
let n = 8;
generateRandom(n);
 
 
// This code is contributed by rag2127
</script>

Output: 
3 4 5 8 6 2 1 7

 

Time Complexity: O(n)
Auxiliary Space: O(n)

Example in c:

 Approach:




#include <iostream>
#include <cstdlib>
#include <ctime>
 
void shuffle(int arr[], int n) {
    for (int i = n - 1; i >= 1; i--) {
        int j = rand() % (i + 1);
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
 
int main() {
    const int n = 10; // example size of permutation
    int arr[n];
    srand(time(NULL)); // seed the random number generator with current time
    for (int i = 0; i < n; i++) {
        arr[i] = i + 1; // initialize array with 1 to N
    }
    shuffle(arr, n); // shuffle the array
    std::cout << "Random permutation of 1 to " << n << ":" << std::endl;
    for (int i = 0; i < n; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    return 0;
}




#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
void shuffle(int arr[], int n) {
    int i;
    for(i = n-1; i >= 1; i--) {
        int j = rand() % (i+1);
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
 
int main() {
    int n = 10; // example size of permutation
    int arr[n];
    int i;
 
    // initialize array with 1 to N
    for(i = 0; i < n; i++) {
        arr[i] = i+1;
    }
 
    // seed the random number generator with current time
    srand(time(NULL));
 
    // shuffle the array
    shuffle(arr, n);
 
    // print the shuffled array
    printf("Random permutation of 1 to %d:\n", n);
    for(i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
 
    return 0;
}




import java.util.Random;
 
public class Main {
 
    static void shuffle(int[] arr, int n) {
        Random rand = new Random();
        for (int i = n - 1; i >= 1; i--) {
            int j = rand.nextInt(i + 1);
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
 
    public static void main(String[] args) {
        final int n = 10; // example size of permutation
        int[] arr = new int[n];
        Random rand = new Random(); // seed the random number generator with current time
        rand.setSeed(System.currentTimeMillis());
        for (int i = 0; i < n; i++) {
            arr[i] = i + 1; // initialize array with 1 to N
        }
        shuffle(arr, n); // shuffle the array
        System.out.println("Random permutation of 1 to " + n + ":");
        for (int i = 0; i < n; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}
 
// This code is contributed by shivhack999




import random
 
# Function to shuffle the array
def shuffle(arr):
    n = len(arr)
    for i in range(n-1, 0, -1):
        j = random.randint(0, i)
        arr[i], arr[j] = arr[j], arr[i]
    return arr
 
 
# Driver Code
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random_permutation = shuffle(arr)
 
print(random_permutation)




using System;
 
class Program
{
    static void Shuffle(int[] arr)
    {
        Random rand = new Random();
        for (int i = arr.Length - 1; i >= 1; i--)
        {
            int j = rand.Next(0, i + 1);
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
 
    static void Main()
    {
        const int n = 10; // example size of permutation
        int[] arr = new int[n];
        Random rand = new Random();
        for (int i = 0; i < n; i++)
        {
            arr[i] = i + 1; // initialize array with 1 to N
        }
        Shuffle(arr); // shuffle the array
        Console.WriteLine("Random permutation of 1 to " + n + ":");
        for (int i = 0; i < n; i++)
        {
            Console.Write(arr[i] + " ");
        }
        Console.WriteLine();
    }
}
// This code is contributed by Prajwal Kandekar




// JavaScript code to shuffle an array
 
function shuffle(arr) {
    for (let i = arr.length - 1; i >= 1; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        let temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
 
const n = 10; // example size of permutation
let arr = new Array(n);
for (let i = 0; i < n; i++) {
    arr[i] = i + 1; // initialize array with 1 to N
}
shuffle(arr); // shuffle the array
console.log(`Random permutation of 1 to ${n}:`);
console.log(arr.join(" "));

Output
Random permutation of 1 to 10:
10 8 9 5 3 1 6 7 4 2 

Time complexity:

1. The shuffle function uses a nested loop to iterate through the array in reverse order, and a constant amount of time for each iteration to perform the swapping operation.
2. Therefore, the time complexity of the shuffle function is O(n).
3. The main function initializes the array, calls the srand and shuffle functions, and prints the shuffled array, which all take constant time.
4. Therefore, the time complexity of the program is also O(n).
 

Space complexity:

1. The program uses a fixed amount of memory for the integer array arr, which has a size of n elements.
2. The shuffle function uses three integer variables (i, j, and temp) and a constant amount of memory for the n argument and the rand function.
3. Therefore, the space complexity of the program is O(n), since we only use a single integer array and a constant amount of memory for the other variables and functions.

One approach to generate N non-repeating random numbers can be as follows:

Here is the implementation of above approach:-




#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
vector<int> generateRandomNumbers(int N) {
    vector<int> numbers(N);
    for(int i = 0; i < N; i++) {
        numbers[i] = i+1;
    }
    srand(time(NULL));
    random_shuffle(numbers.begin(), numbers.end());
    return vector<int>(numbers.begin(), numbers.begin() + N);
}
 
int main() {
    int N = 8;
    vector<int> numbers = generateRandomNumbers(N);
    for(int i = 0; i < N; i++) {
        cout << numbers[i] << " ";
    }
    cout << endl;
    return 0;
}




import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        int N = 8;
        List<Integer> numbers = generateRandomNumbers(N);
        for(int i = 0; i < N; i++) {
            System.out.print(numbers.get(i) + " ");
        }
        System.out.println();
    }
     
    public static List<Integer> generateRandomNumbers(int N) {
        List<Integer> numbers = new ArrayList<>();
        for(int i = 1; i <= N; i++) {
            numbers.add(i);
        }
        Collections.shuffle(numbers);
        return numbers.subList(0, N);
    }
}




import random
 
def generateRandomNumbers(N):
    numbers = list(range(1, N+1))
    random.shuffle(numbers)
    return numbers[:N]
 
if __name__ == "__main__" :
    n = 8
    numbers = generateRandomNumbers(n)
    print(numbers)




using System;
using System.Collections.Generic;
 
class MainClass {
    static void Main() {
        int N = 8;
        List<int> numbers = GenerateRandomNumbers(N);
        foreach(int number in numbers) {
            Console.Write(number + " ");
        }
        Console.WriteLine();
    }
     
    static List<int> GenerateRandomNumbers(int N) {
        List<int> numbers = new List<int>();
        for(int i = 1; i <= N; i++) {
            numbers.Add(i);
        }
        Random rnd = new Random();
        for(int i = N - 1; i > 0; i--) {
            int j = rnd.Next(i + 1);
            int temp = numbers[i];
            numbers[i] = numbers[j];
            numbers[j] = temp;
        }
        return numbers.GetRange(0, N);
    }
}




<?php
function generateRandomNumbers($N) {
    $numbers = range(1, $N);
    shuffle($numbers);
    return array_slice($numbers, 0, $N);
}
 
$n = 8;
$numbers = generateRandomNumbers($n);
foreach($numbers as $number) {
    echo $number . " ";
}
echo "\n";
?>




function generateRandomNumbers(N) {
    let numbers = [];
    for(let i = 1; i <= N; i++) {
        numbers.push(i);
    }
    for(let i = N - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        let temp = numbers[i];
        numbers[i] = numbers[j];
        numbers[j] = temp;
    }
    return numbers.slice(0, N);
}
 
let n = 8;
let numbers = generateRandomNumbers(n);
console.log(numbers.join(" "));

Output
2 6 8 7 1 4 3 5 

Time complexity: O(N)
Auxiliary Space: O(N)


Article Tags :