Count unimodal and non-unimodal permutations of first N natural numbers

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:
- Construct unimodal permutations of length N in an infinite length array.
- 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.
- 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.
- This continues for all elements down to 1. Observe that there are two choices for each element except N.
- So the number of unimodal permutations of length N will be 2N – 1
- The total number of permutations will be N!.
- 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 numbervoid 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 Nvoid 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 Codeint main(){Â Â Â Â // Given Number NÂ Â Â Â int N = 4;Â
    // Function Call    countPermutations(N);Â
    return 0;} |
Java
// Java program for// the above approachclass 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 approachmod = 1e9 + 7mx = 1000000fact = [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 NN = 4Â
# Function callcountPermutations(N)Â
# This code is contributed by code_hunt |
C#
// C# program for// the above approachusing 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> |
8 16
Time Complexity: O(N)Â
Auxiliary Space: O(N)
Efficient approach : Space optimization O(1)
In previous approach we use fact[] to calculate the factorial of n but the we can calculate factorial using variable to optimize space complexity.
Implementation steps:
- The approach is very similar to the previous approach the difference is only in the calculate_factorial.
- Initialize the variable fact with 1.
- Now iterate from 1 to N and get the factorial.
- return the factorial to countPermutations function where we print the uni_model and nonuni_model.
Implementation:
C++
// C++ program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
int mod = 1e9 + 7;Â
// Function to calculate the// factorials up to a numberint Calculate_factorial(int n){Â Â Â Â int fact = 1;Â
    // Calculate the factorial    for (int i = 1; i <= n; i++) {        fact = (fact * i) % mod;    }Â
    return fact;}Â
// 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) % mod;        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 Nvoid countPermutations(int n){Â
    // Function Call for finding    // factorials up to N    int factN = Calculate_factorial(n);Â
    // Function to count unimodal    // permutations    int uni_modal = UniModal_per(2, n - 1);Â
    // Non-unimodal permutation is    // N! - unimodal permutations    int nonuni_modal = factN - uni_modal;Â
    cout << uni_modal << " " << nonuni_modal;Â
    return;}Â
// Driver Codeint main(){Â Â Â Â // Given Number NÂ Â Â Â int N = 4;Â
    // Function Call    countPermutations(N);Â
    return 0;} |
Java
// Java program for the above approachimport java.util.*;public class Main {Â
  static int mod = 1000000007;Â
  // Function to calculate the factorials up to a number  static int Calculate_factorial(int n) {    int fact = 1;Â
    // Calculate the factorial    for (int i = 1; i <= n; i++) {      fact = (int)(((long)fact * i) % mod);    }Â
    return fact;  }Â
  // Function to find power(a, b)  static int UniModal_per(int a, int b) {    long res = 1;Â
    // Iterate until b exists    while (b != 0) {Â
      // If b is divisible by 2      if ((b & 1) == 1) {        res = (res * a) % mod;      }      a = (int)(((long)a * a) % mod);Â
      // Decrease the value of b      b >>= 1;    }Â
    // Return the answer    return (int)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    int factN = Calculate_factorial(n);Â
    // Function to count unimodal permutations    int uni_modal = UniModal_per(2, n - 1);Â
    // Non-unimodal permutation is N! - unimodal permutations    int nonuni_modal = factN - uni_modal;Â
    System.out.println(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 rishabmalhdijo |
Python3
# codemod = 10**9 + 7Â
# Function to calculate the# factorials up to a numberdef Calculate_factorial(n):Â Â Â Â fact = 1Â
    # Calculate the factorial    for i in range(1, n+1):        fact = (fact * i) % modÂ
    return factÂ
# Function to find power(a, b)def UniModal_per(a, b):Â Â Â Â res = 1Â
    # Iterate until b exists    while b:Â
        # If b is divisible by 2        if b % 2:            res = (res * a) % mod        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 Ndef countPermutations(n):Â
    # Function Call for finding    # factorials up to N    factN = Calculate_factorial(n)Â
    # Function to count unimodal    # permutations    uni_modal = UniModal_per(2, n - 1)Â
    # Non-unimodal permutation is    # N! - unimodal permutations    nonuni_modal = factN - uni_modalÂ
    print(uni_modal, nonuni_modal)Â
    returnÂ
# Driver Codeif __name__ == '__main__':Â Â Â Â # Given Number NÂ Â Â Â N = 4Â
    # Function Call    countPermutations(N) |
C#
using System;Â
public class GFG {Â Â static int mod = 1000000007;Â
  // Function to calculate the  // factorials up to a number  static int Calculate_factorial(int n)  {    int fact = 1;Â
    // Calculate the factorial    for (int i = 1; i <= n; i++) {      fact = (fact * i) % mod;    }Â
    return fact;  }Â
  // Function to find power(a, b)  static int UniModal_per(int a, int b)  {    long res = 1;Â
    // Iterate until b exists    while (b > 0) {Â
      // If b is divisible by 2      if (b % 2 == 1)        res = (res * a) % mod;      a = (a * a) % mod;Â
      // Decrease the value of b      b /= 2;    }Â
    // Return the answer    return (int)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    int factN = Calculate_factorial(n);Â
    // Function to count unimodal    // permutations    int uni_modal = UniModal_per(2, n - 1);Â
    // Non-unimodal permutation is    // N! - unimodal permutations    int nonuni_modal = factN - uni_modal;Â
    Console.WriteLine(uni_modal + " " + nonuni_modal);Â
    return;  }Â
  // Driver Code  public static void Main()  {    // Given Number N    int N = 4;Â
    // Function Call    countPermutations(N);  }}Â
// This code is contributed by sarojmcy2e |
Javascript
const mod = 1000000007;Â
// Function to calculate the factorials up to a numberfunction calculateFactorial(n) {Â Â let fact = 1;Â
  // Calculate the factorial  for (let i = 1; i <= n; i++) {    fact = (fact * i) % mod;  }Â
  return fact;}Â
// Function to find power(a, b)function unimodalPer(a, b) {Â Â let res = 1;Â
  // Iterate until b exists  while (b !== 0) {Â
    // If b is divisible by 2    if ((b & 1) === 1) {      res = (res * a) % mod;    }    a = (a * a) % mod;Â
    // Decrease the value of b    b >>= 1;  }Â
  // Return the answer  return res;}Â
// Function that counts the unimodal and non-unimodal permutations // of a given integer Nfunction countPermutations(n) {Â
  // Function Call for finding factorials up to N  const factN = calculateFactorial(n);Â
  // Function to count unimodal permutations  const uni_modal = unimodalPer(2, n - 1);Â
  // Non-unimodal permutation is N! - unimodal permutations  const nonuni_modal = factN - uni_modal;Â
  console.log(`${uni_modal} ${nonuni_modal}`);}Â
// Driver Codeconst N = 4;Â
// Function CallcountPermutations(N); |
Output
8 16
Time Complexity: O(N), Where N is the input variable
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



