Skip to content
Related Articles

Related Articles

Improve Article
Count unimodal and non-unimodal permutations of first N natural numbers
  • Difficulty Level : Medium
  • Last Updated : 29 May, 2021

Given an integer N, the task is to count the total number of unimodal and non-unimodal permutations of integers [1, N] possible.

An unimodal permutation is a permutation which increases up to a certain point following which it starts decreasing. 
All other permutations, excluding unimodal permutations, are non-unimodal permutations.

Note: Since the total count can be very large, so print modulo 109+7.

Examples:

Input: N = 3 
Output: 4 2 
Explanation: 
All possible unimodal permutations are {1, 2, 3}, {1, 3, 2}, {2, 3, 1}, {3, 2, 1}. 
Therefore, the count of unimodal permutations is 4. 
Remaining permutations are {2, 1, 3}, {3, 1, 2}. 
Therefore, the count of non-unimodal permutations is 2.



Input: N = 4 
Output: 8 16

Naive Approach: The simplest approach is to generate all possible permutations of integers from the range [1, N] and then print the count of all those permutations that are unimodal. Print the count of unimodal as well as non-unimodal permutations accordingly. 
Time Complexity: O(N!) 
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to first find the total number of unimodal permutations possible for a given integer N and then to find the count of non-unimodal permutations to subtract the count of unimodal permutations from the count of total permutations. Below are the steps:

  1. Construct unimodal permutations of length N in an infinite length array.
  2. Place N anywhere in the permutation, then there are exactly two positions at which the (N – 1)th element can be placed, i.e., either to the left or to the right of N.
  3. Suppose it goes to the right. Now, the (N – 2)th element can be put either to the left or to the right in the current permutation.
  4. This continues for all elements down to 1. Observe that there are two choices for each element except N.
  5. So the number of unimodal permutations of length N will be 2N – 1
  6. The total number of permutations will be N!.
  7. Now the total number of non-uni modal permutations will be equal to (N! – unimodal permutations).

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
int mod = 1e9 + 7;
const int mx = 1e6;
int fact[mx + 1];
 
// Function to calculate the
// factorials up to a number
void Calculate_factorial()
{
    fact[0] = 1;
 
    // Calculate the factorial
    for (int i = 1; i <= mx; i++) {
        fact[i] = i * fact[i - 1];
        fact[i] %= mod;
    }
}
 
// Function to find power(a, b)
int UniModal_per(int a, int b)
{
    long long int res = 1;
 
    // Iterate until b exists
    while (b) {
 
        // If b is divisible by 2
        if (b % 2)
            res = res * a;
        res %= mod;
        a = a * a;
        a %= mod;
 
        // Decrease the value of b
        b /= 2;
    }
 
    // Return the answer
    return res;
}
 
// Function that counts the unimodal
// and non-unimodal permutations of
// a given integer N
void countPermutations(int n)
{
 
    // Function Call for finding
    // factorials up to N
    Calculate_factorial();
 
    // Function to count unimodal
    // permutations
    int uni_modal = UniModal_per(2, n - 1);
 
    // Non-unimodal permutation is
    // N! - unimodal permutations
    int nonuni_modal = fact[n] - uni_modal;
 
    cout << uni_modal << " " << nonuni_modal;
 
    return;
}
 
// Driver Code
int main()
{
    // Given Number N
    int N = 4;
 
    // Function Call
    countPermutations(N);
 
    return 0;
}

Java




// Java program for
// the above approach
class GFG {
 
    static int mod = (int)(1e9 + 7);
    static int mx = (int)1e6;
    static int[] fact = new int[(int)mx + 1];
 
    // Function to calculate the
    // factorials up to a number
    static void Calculate_factorial()
    {
        fact[0] = 1;
 
        // Calculate the factorial
        for (int i = 1; i <= mx; i++) {
            fact[i] = i * fact[i - 1];
            fact[i] %= mod;
        }
    }
 
    // Function to find power(a, b)
    static int UniModal_per(int a, int b)
    {
        int res = 1;
 
        // Iterate until b exists
        while (b > 0) {
            // If b is divisible by 2
            if (b % 2 != 0)
                res = res * a;
            res %= mod;
            a = a * a;
            a %= mod;
 
            // Decrease the value of b
            b /= 2;
        }
 
        // Return the answer
        return res;
    }
 
    // Function that counts the unimodal
    // and non-unimodal permutations of
    // a given integer N
    static void countPermutations(int n)
    {
        // Function Call for finding
        // factorials up to N
        Calculate_factorial();
 
        // Function to count unimodal
        // permutations
        int uni_modal = UniModal_per(2, n - 1);
 
        // Non-unimodal permutation is
        // N! - unimodal permutations
        int nonuni_modal = fact[n] - uni_modal;
 
        System.out.print(uni_modal + " " + nonuni_modal);
 
        return;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given Number N
        int N = 4;
 
        // Function Call
        countPermutations(N);
    }
}
 
// This code is contributed by shikhasingrajput

Python3




# Python3 program for the above approach
mod = 1e9 + 7
mx = 1000000
fact = [0] * (mx + 1)
 
# Function to calculate the
# factorials up to a number
 
 
def Calculate_factorial():
 
    fact[0] = 1
 
    # Calculate the factorial
    for i in range(1, mx + 1):
        fact[i] = i * fact[i - 1]
        fact[i] %= mod
 
# Function to find power(a, b)
 
 
def UniModal_per(a, b):
 
    res = 1
 
    # Iterate until b exists
    while (b != 0):
 
        # If b is divisible by 2
        if (b % 2 != 0):
            res = res * a
 
        res %= mod
        a = a * a
        a %= mod
 
        # Decrease the value of b
        b //= 2
 
    # Return the answer
    return res
 
# Function that counts the unimodal
# and non-unimodal permutations of
# a given integer N
 
 
def countPermutations(n):
 
    # Function Call for finding
    # factorials up to N
    Calculate_factorial()
 
    # Function to count unimodal
    # permutations
    uni_modal = UniModal_per(2, n - 1)
 
    # Non-unimodal permutation is
    # N! - unimodal permutations
    nonuni_modal = fact[n] - uni_modal
 
    print(int(uni_modal), "",
          int(nonuni_modal))
 
    return
 
# Driver Code
# Given number N
N = 4
 
# Function call
countPermutations(N)
 
# This code is contributed by code_hunt

C#




// C# program for
// the above approach
using System;
class GFG
{
    static int mod = (int)(1e9 + 7);
    static int mx = (int)1e6;
    static int[] fact = new int[(int)mx + 1];
 
    // Function to calculate the
    // factorials up to a number
    static void Calculate_factorial()
    {
        fact[0] = 1;
 
        // Calculate the factorial
        for (int i = 1; i <= mx; i++)
        {
            fact[i] = i * fact[i - 1];
            fact[i] %= mod;
        }
    }
 
    // Function to find power(a, b)
    static int UniModal_per(int a, int b)
    {
        int res = 1;
 
        // Iterate until b exists
        while (b > 0)
        {
            // If b is divisible by 2
            if (b % 2 != 0)
                res = res * a;
 
            res %= mod;
            a = a * a;
            a %= mod;
 
            // Decrease the value of b
            b /= 2;
        }
 
        // Return the answer
        return res;
    }
 
    // Function that counts the unimodal
    // and non-unimodal permutations of
    // a given integer N
    static void countPermutations(int n)
    {
        // Function Call for finding
        // factorials up to N
        Calculate_factorial();
 
        // Function to count unimodal
        // permutations
        int uni_modal = UniModal_per(2, n - 1);
 
        // Non-unimodal permutation is
        // N! - unimodal permutations
        int nonuni_modal = fact[n] - uni_modal;
 
        Console.Write(uni_modal + " " + nonuni_modal);
        return;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        // Given Number N
        int N = 4;
 
        // Function Call
        countPermutations(N);
    }
}
 
// This code is contributed by shikhasingrajput

Javascript




<script>
      // JavaScript program for
      // the above approach
      var mod = parseInt(1e9 + 7);
      var mx = 1000000;
      var fact = new Array(mx + 1).fill(0);
 
      // Function to calculate the
      // factorials up to a number
      function Calculate_factorial() {
        fact[0] = 1;
 
        // Calculate the factorial
        for (var i = 1; i <= mx; i++) {
          fact[i] = i * fact[i - 1];
          fact[i] %= mod;
        }
      }
 
      // Function to find power(a, b)
      function UniModal_per(a, b) {
        var res = 1;
 
        // Iterate until b exists
        while (b > 0) {
          // If b is divisible by 2
          if (b % 2 !== 0) res = res * a;
 
          res %= mod;
          a = a * a;
          a %= mod;
 
          // Decrease the value of b
          b = parseInt(b / 2);
        }
 
        // Return the answer
        return res;
      }
 
      // Function that counts the unimodal
      // and non-unimodal permutations of
      // a given integer N
      function countPermutations(n) {
        // Function Call for finding
        // factorials up to N
        Calculate_factorial();
 
        // Function to count unimodal
        // permutations
        var uni_modal = UniModal_per(2, n - 1);
 
        // Non-unimodal permutation is
        // N! - unimodal permutations
        var nonuni_modal = fact[n] - uni_modal;
 
        document.write(uni_modal + " " + nonuni_modal);
        return;
      }
 
      // Driver Code
      // Given Number N
      var N = 4;
 
      // Function Call
      countPermutations(N);
    </script>
Output
8 16

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

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.




My Personal Notes arrow_drop_up
Recommended Articles
Page :