Open In App

Smallest Derangement of Sequence

Last Updated : 21 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given the sequence 

\ S = {1, 2, 3 \dots N}
find the lexicographically smallest (earliest in dictionary order) derangement of 
\ S
A derangement of S is any permutation of S such that no two elements in S and its permutation occur at the same position.

Examples:   

Input: 3
Output : 2 3 1
Explanation: The Sequence is 1 2 3.
Possible permutations are (1, 2, 3), (1, 3, 2),
          (2, 1, 3), (2, 3, 1), (3, 1, 2) (3, 2, 1).
Derangements are (2, 3, 1), (3, 1, 2).
Smallest Derangement: (2, 3, 1)

Input : 5
Output : 2 1 4 5 3.
Explanation: Out of all the permutations of 
(1, 2, 3, 4, 5), (2, 1, 4, 5, 3) is the first derangement.

Method 1: 

We can modify the method shown in this article: Largest Derangement 
Using a min heap we can successively get the least element and place them in more significant positions, taking care that the property of derangement is maintained. 

Below is the implementation of the above approach.   

C++

// C++ program to generate smallest derangement
// using priority queue.
#include <bits/stdc++.h>
using namespace std;
 
void generate_derangement(int N)
{
    // Generate Sequence and insert into a
    // priority queue.
    int S[N + 1];
    priority_queue<int, vector<int>, greater<int> > PQ;
    for (int i = 1; i <= N; i++) {
        S[i] = i;
        PQ.push(S[i]);
    }
 
    // Generate Least Derangement
    int D[N + 1];
    for (int i = 1; i <= N; i++) {
        int d = PQ.top();
        PQ.pop();
        if (d != S[i] || i == N) {
            D[i] = d;
        }
        else {
            D[i] = PQ.top();
            PQ.pop();
            PQ.push(d);
        }
    }
 
    if (D[N] == S[N])
       swap(D[N-1], D[N]);
 
    // Print Derangement
    for (int i = 1; i <= N; i++)
        printf("%d ", D[i]);   
    printf("\n");
}
 
// Driver code
int main()
{
    generate_derangement(10);
    return 0;
}

                    

Java

// Java program to generate
// smallest derangement
// using priority queue.
import java.util.*;
class GFG{
 
static void generate_derangement(int N)
{
  // Generate Sequence and insert
  // into a priority queue.
  int []S = new int[N + 1];
   
  PriorityQueue<Integer> PQ =
                new PriorityQueue <>();
   
  for (int i = 1; i <= N; i++)
  {
    S[i] = i;
    PQ.add(S[i]);
  }
 
  // Generate Least Derangement
  int []D = new int[N + 1];
   
  for (int i = 1; i <= N; i++)
  {
    int d = PQ.peek();
    PQ.remove();
    if (d != S[i] || i == N)
    {
      D[i] = d;
    }
    else
    {
      D[i] = PQ.peek();
      PQ.remove();
      PQ.add(d);
    }
  }
 
  if (D[N] == S[N])
  {
    int t = D[N - 1];
    D[N - 1] = D[N];
    D[N] = t;
  }
 
  // Print Derangement
  for (int i = 1; i <= N; i++)
    System.out.printf("%d ", D[i]);   
  System.out.printf("\n");
}
 
// Driver code
public static void main(String[] args)
{
  generate_derangement(10);
}
}
 
// This code is contributed by Amit Katiyar

                    

Python3

# Python3 program to generate
# smallest derangement
# using priority queue.
def generate_derangement(N) :
     
    # Generate Sequence and insert
    # into a priority queue.
    S = [i for i in range(N + 1)]   
    PQ = []   
    for i in range(1, N + 1) :      
        PQ.append(S[i])
         
    # Generate Least Derangement
    D = [0] * (N + 1)   
    PQ.sort()  
    for i in range(1, N + 1) :     
        PQ.sort()     
        d = PQ[0]
        del PQ[0]    
        if (d != S[i]) or (i == N) :        
            D[i] = d         
        else :        
            PQ.sort()
            D[i] = PQ[0]
            del PQ[0]
            PQ.append(d)           
    if D[N] == S[N] :       
        t = D[N - 1]
        D[N - 1] = D[N]
        D[N] = t
         
    # Print Derangement
    for i in range(1, N + 1) :
        print(D[i], end = " ")       
    print()
     
generate_derangement(10)
 
# This code is contributed by divyeshrabadiya07

                    

C#

// C# program to generate
// smallest derangement
// using priority queue.
using System;
using System.Collections.Generic;
 
class GFG{
 
static void generate_derangement(int N)
{
   
  // Generate Sequence and insert
  // into a priority queue.
  int []S = new int[N + 1];
   
  List<int> PQ = new List <int>();
   
  for(int i = 1; i <= N; i++)
  {
    S[i] = i;
    PQ.Add(S[i]);
  }
 
  // Generate Least Derangement
  int []D = new int[N + 1];
  PQ.Sort();
  for(int i = 1; i <= N; i++)
  {
    PQ.Sort();
     
    int d = PQ[0];
    PQ.RemoveAt(0);
     
    if (d != S[i] || i == N)
    {
      D[i] = d;
    }
    else
    {
      PQ.Sort();
      D[i] = PQ[0];
      PQ.RemoveAt(0);
      PQ.Add(d);
    }
  }
 
  if (D[N] == S[N])
  {
    int t = D[N - 1];
    D[N - 1] = D[N];
    D[N] = t;
  }
 
  // Print Derangement
  for(int i = 1; i <= N; i++)
    Console.Write(D[i] + " "); 
   
  Console.Write("\n");
}
 
// Driver code
public static void Main(String[] args)
{
  generate_derangement(10);
}
}
 
// This code is contributed by Amit Katiyar

                    

Javascript

<script>
// Javascript program to generate
// smallest derangement
// using priority queue.
 
function generate_derangement(N)
{
 
    // Generate Sequence and insert
  // into a priority queue.
  let S = new Array(N + 1);
    
  let PQ =[];
    
  for (let i = 1; i <= N; i++)
  {
    S[i] = i;
    PQ.push(S[i]);
  }
  
 PQ.sort(function(a,b){return a-b;});   
  
  // Generate Least Derangement
  let D = new Array(N + 1);
    
  for (let i = 1; i <= N; i++)
  {
    let d = PQ.shift();
     
    if (d != S[i] || i == N)
    {
      D[i] = d;
    }
    else
    {
      D[i] = PQ.shift();
       
      PQ.push(d);
    }
    PQ.sort(function(a,b){return a-b;});
  }
  
  if (D[N] == S[N])
  {
    let t = D[N - 1];
    D[N - 1] = D[N];
    D[N] = t;
  }
  
  // Print Derangement
  for (let i = 1; i <= N; i++)
    document.write( D[i]+" ");  
  document.write("<br>");
}
 
// Driver code
generate_derangement(10);
 
// This code is contributed by avanitrachhadiya2155
</script>

                    

Output
2 1 4 3 6 5 8 7 10 9 

Time Complexity: O(N * log N).
Auxiliary Space: O(N)

Method 2: 
Since we are given a very specific sequence i.e 

S_i = i \ \ \forall i <= N

We can calculate the answer even more efficiently.
Divide the original sequence into pairs of two elements, and then swap the elements of each pair. 
If N is odd then the last pair needs to be swapped again. 

Pictorial Representation  

Complexity: We perform at most N/2 + 1 swaps, so the complexity is O(N).

Why does this method work 
This method is a very specific application of method 1 and is based on observation. Given the nature of the sequence, at position i we already know the least element that can be put, which is either i+1 or i-1. Since we are already given the least permutation of S it is clear that the derangement must start from 2 and not 1 ie of the form i+1 (i = 1). The next element will be of form i – 1 . The element after this will be i + 1 and then next i – 1. This pattern will continue until the end. 
This operation is most easily understood as the swapping of adjacent elements of pairs of elements of S.
If we can determine the least element in constant time, then the complexity overhead from the heap is eliminated. Hence, from O(N * log N) the complexity reduces to O(N). 

Below is the implementation of the above approach: 

Implementation:

C++

// Efficient C++ program to find smallest
// derangement.
#include <bits/stdc++.h>
 
void generate_derangement(int N)
{       
    // Generate Sequence S
    int S[N + 1];
    for (int i = 1; i <= N; i++)
        S[i] = i;
 
    // Generate Derangement
    int D[N + 1];
    for (int i = 1; i <= N; i += 2) {
        if (i == N && i%N!=0) {
 
            // Only if i is odd
            // Swap D[N-1] and D[N]
            int temp=D[N];
            D[N] = D[N - 1];
            D[N - 1] = temp;
        }
        else {
            D[i] = i + 1;
            D[i + 1] = i;
        }
    }
 
    // Print Derangement
    for (int i = 1; i <= N; i++)
        printf("%d ", D[i]);   
    printf("\n");
}
 
// Driver Program
int main()
{
    generate_derangement(10);
    return 0;
}

                    

Java

// Efficient Java program to find
// smallest derangement.
class GFG
{
     
static void generate_derangement(int N)
{
    // Generate Sequence S
    int S[] = new int[N + 1];
    for (int i = 1; i <= N; i++)
        S[i] = i;
 
    // Generate Derangement
    int D[] = new int[N + 1];
    for (int i = 1; i <= N; i += 2)
    {
        if (i == N)
        {
 
            // Only if i is odd
            // Swap S[N-1] and S[N]
            D[N] = S[N - 1];
            D[N - 1] = S[N];
        }
        else
        {
            D[i] = i + 1;
            D[i + 1] = i;
        }
    }
 
    // Print Derangement
    for (int i = 1; i <= N; i++)
        System.out.print(D[i] + " ");
    System.out.println();
}
 
// Driver Program
public static void main(String[] args)
{
    generate_derangement(10);
}
}
 
// This code is contributed by Arnab Kundu

                    

Python3

# Efficient Python3 program to find
# smallest derangement.
 
def generate_derangement(N):
     
    # Generate Sequence S
    S = [0] * (N + 1)
    for i in range(1, N + 1):
        S[i] = i
 
    # Generate Derangement
    D = [0] * (N + 1)
    for i in range(1, N + 1, 2):
        if i == N:
 
            # Only if i is odd
            # Swap S[N-1] and S[N]
            D[N] = S[N - 1]
            D[N - 1] = S[N]
        else:
            D[i] = i + 1
            D[i + 1] = i
 
    # Print Derangement
    for i in range(1, N + 1):
        print(D[i], end = " ")
    print()
 
# Driver Code
if __name__ == '__main__':
    generate_derangement(10)
     
# This code is contributed by PranchalK

                    

C#

// Efficient C# program to find
// smallest derangement.
using System;
 
class GFG
{
     
static void generate_derangement(int N)
{
    // Generate Sequence S
    int[] S = new int[N + 1];
    for (int i = 1; i <= N; i++)
        S[i] = i;
 
    // Generate Derangement
    int[] D = new int[N + 1];
    for (int i = 1; i <= N; i += 2)
    {
        if (i == N)
        {
 
            // Only if i is odd
            // Swap S[N-1] and S[N]
            D[N] = S[N - 1];
            D[N - 1] = S[N];
        }
        else
        {
            D[i] = i + 1;
            D[i + 1] = i;
        }
    }
 
    // Print Derangement
    for (int i = 1; i <= N; i++)
        Console.Write(D[i] + " ");
    Console.WriteLine();
}
 
// Driver Program
public static void Main()
{
    generate_derangement(10);
}
}
 
// This code is contributed
// by Akanksha Rai

                    

PHP

<?php
// Efficient PHP program to find smallest
// derangement.
 
function generate_derangement($N)
{    
    // Generate Sequence S
    $S = array();
    for ($i = 1; $i <= $N; $i++)
        $S[$i] = $i;
 
    // Generate Derangement
    $D = array();
    for ($i = 1; $i <= $N; $i += 2)
    {
        if ($i == $N)
        {
 
            // Only if i is odd
            // Swap S[N-1] and S[N]
            $D[$N] = $S[$N - 1];
            $D[$N - 1] = $S[$N];
        }
        else
        {
            $D[$i] = $i + 1;
            $D[$i + 1] = $i;
        }
    }
 
    // Print Derangement
    for ($i = 1; $i <= $N; $i++)
        echo $D[$i] . " ";
    echo "\n";
}
 
// Driver Program
generate_derangement(10);
 
// This code is contributed
// by Akanksha Rai
?>

                    

Javascript

<script>
 
// Javascript program to find
// smallest derangement.
function generate_derangement(N)
{
 
    // Generate Sequence S
    let S = [];
    for (let i = 1; i <= N; i++)
        S[i] = i;
  
    // Generate Derangement
    let D = [];
    for (let i = 1; i <= N; i += 2)
    {
        if (i == N)
        {
  
            // Only if i is odd
            // Swap S[N-1] and S[N]
            D[N] = S[N - 1];
            D[N - 1] = S[N];
        }
        else
        {
            D[i] = i + 1;
            D[i + 1] = i;
        }
    }
  
    // Print Derangement
    for (let i = 1; i <= N; i++)
        document.write(D[i] + " ");
    document.write("<br/>");
 }
 
     
// Driver code
        generate_derangement(10);
       
      // This code is contributed by code_hunt.
</script>

                    

Output
2 1 4 3 6 5 8 7 10 9 

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

Note: The auxiliary space can be reduced to O(1) if we perform the swapping operations on S itself.

 



Previous Article
Next Article

Similar Reads

Largest Derangement of a Sequence
Given any sequence, find the largest derangement of .A derangement [Tex]D [/Tex]is any permutation of, such that no two elements at the same position in [Tex]S [/Tex]and [Tex]D [/Tex]are equal. The Largest Derangement is such that. Examples: Input : seq[] = {5, 4, 3, 2, 1}Output : 4 5 2 1 3 Input : seq[] = {56, 21, 42, 67, 23, 74}Output : 74, 67, 5
7 min read
Minimum operations required to transform a sequence of numbers to a sequence where a[i]=a[i+2]
Given a sequence of integers of even length 'n', the task is to find the minimum number of operations required to convert the sequence to follow the rule a[i]=a[i+2] where 'i' is the index. The operation here is to replace any element of the sequence with any element. Examples: Input : n=4 ; Array : 3, 1, 3, 2 Output : 1 If we change the last eleme
11 min read
Convert an unbalanced bracket sequence to a balanced sequence
Given an unbalanced bracket sequence of '(' and ')', convert it into a balanced sequence by adding the minimum number of '(' at the beginning of the string and ')' at the end of the string. Examples: Input: str = ")))()" Output: "((()))()" Input: str = "())())(())())" Output: "(((())())(())())" Method 1: Approach: Initialize an empty stack.Iterate
13 min read
Find original sequence from Array containing the sequence merged many times in order
Given a number N and an array arr[] that consist of merging N length sequence of distinct integers any number of times maintaining the relative order of elements in the initial sequence. The task is to find the initial sequence of length N maintaining the right order. Examples: Input: N = 4, arr[] = {1, 13, 1, 24, 13, 24, 2, 2}Output: 1 13 24 2 Exp
10 min read
Find a valid parenthesis sequence of length K from a given valid parenthesis sequence
Given a string S of valid parentheses sequence of length N and an even integer K, the task is to find the valid parentheses sequence of length K which is also a subsequence of the given string. Note: There can be more than one valid sequence, print any of them. Examples: Input: S = "()()()", K = 4Output: ()()Explanation:The string "()()" is a subse
7 min read
Generate a sequence X from given sequence Y such that Yi = gcd(X1, X2 , ... , Xi)
Given a sequence Y of size N where: Yi = gcd(X1, X2, X3, . . ., Xi ) of some sequence X. The task is to find such a sequence X if any such X is possible. Note: If X exists there can be multiple value possible for X. Generating any one is sufficient. Examples: Input: N = 2, Y = [4, 2]Output: [4, 2]Explanation: Y0 = gcd(X0) = X0 = 4. And gcd(4, 2) =
7 min read
k-th missing element in increasing sequence which is not present in a given sequence
Given two sequences, one is increasing sequence a[] and another a normal sequence b[], find the K-th missing element in the increasing sequence which is not present in the given sequence. If no k-th missing element is there output -1 Examples: Input: a[] = {0, 2, 4, 6, 8, 10, 12, 14, 15}; b[] = {4, 10, 6, 8, 12}; k = 3 Output: 14 Explanation : The
6 min read
Find the lexicographically smallest sequence which can be formed by re-arranging elements of second array
Given two arrays A and B of N integers. Reorder the elements of B in itself in such a way that the sequence formed by (A[i] + B[i]) % N after re-ordering is the smallest lexicographically. The task is to print the lexicographically smallest sequence possible. Note: The array elements are in range [0, n).Examples: Input: a[] = {0, 1, 2, 1}, b[] = {3
11 min read
Nth term of a sequence formed by sum of current term with product of its largest and smallest digit
Given two numbers N and K, where K represents the starting term of the sequence. The task is to find the Nth term of a sequence formed by sum of current term with product of largest and smallest digit of current term, i.e., AN+1 = AN + max(digits of AN) * min(digits of AN) Examples: Input: K = 1, N = 5 Output: 50 Explanation: A1 = 1 A2 = A1 + minDi
6 min read
Length of smallest sequence having sum X and product Y
Given two integers X and Y, the task is to find the length of the smallest sequence consisting of positive integers having sum X and product Y. If no such sequence can be generated, print -1. Examples: Input: X = 5, Y = 5Output: 1Explanation:The smallest possible sequence having sum 5 and product 5 is {5}. Therefore, the required answer is length o
7 min read
Article Tags :
Practice Tags :
three90RightbarBannerImg