Given an array arr[] of size n, the task is to print the lexicographically next greater permutation of the given array. If there does not exist any greater permutation, then find the lexicographically smallest permutation of the given array.
Let us understand the problem better by writing all permutations of [1, 2, 4] in lexicographical order: [1, 2, 4], [1, 4, 2], [2, 1, 4], [2, 4, 1], [4, 1, 2] and [4, 2, 1]. If we give any of the above (except the last) as input, we need to find the next one in sequence. If we give last as input, we need to return the first one.
Examples:
Input: arr = [2, 4, 1, 7, 5, 0]
Output: [2, 4, 5, 0, 1, 7]
Explanation: The next permutation of the given array is 2 4 5 0 1 7
Input: arr = {3, 2, 1]
Output: [1, 2, 3]
Explanation: As arr[] is the last permutation. So, the next permutation is the lowest one.
Input: arr = [1, 3, 5, 4, 2]
Output: [1, 4, 2, 3, 5]
Explanation: The next permutation of the given array is found by rearranging the elements in the next lexicographical order.
[Naive Approach] Generating All Permutations - O(n!*n*log(n!)) Time and O(n!) Space
The very basic idea that comes to our mind is that we would first generate all possible permutations of a given array and sort them. Once sorted, we locate the current permutation within this list. The next permutation is simply the next arrangement in the sorted order. If the current arrangement is the last in the list then display the first permutation (smallest permutation).
Note: This approach will work only when there are no duplicated in the input array. Please refer the expected approach to handle duplicates.
C++
// C++ Program to find the next permutation by generating
// all permutations
#include <bits/stdc++.h>
using namespace std;
// Generates all permutations
void permutations(vector<vector<int>>& res, vector<int>& curr,
int idx);
// Function to get the next permutation
void nextPermutation(vector<int>& arr) {
// Generate all permutations and store in res
vector<vector<int>> res;
permutations(res, arr, 0);
sort(res.begin(), res.end());
// Traverse through res and find the next permutation
for (int i = 0; i < res.size(); i++) {
// Found a match
if (res[i] == arr) {
// Store the next
if (i < res.size() - 1)
arr = res[i + 1];
// If the given permutation is the last
if (i == res.size() - 1)
arr = res[0];
break;
}
}
}
// Function to generate all possible permutations
void permutations(vector<vector<int>>& res, vector<int>& arr,
int idx) {
// Base case: if idx reaches the end of the array
if (idx == arr.size() - 1) {
res.push_back(arr);
return;
}
// Permutations made by swapping each element
// starting from index `idx`
for (int i = idx; i < arr.size(); i++) {
// Swapping
swap(arr[idx], arr[i]);
// Recursive call to create permutations
// for the next element
permutations(res, arr, idx + 1);
// Backtracking
swap(arr[idx], arr[i]);
}
}
int main() {
vector<int> arr = { 2, 4, 1, 7, 5, 0 };
nextPermutation(arr);
for (int i = 0; i < arr.size(); i++) {
cout << arr[i] << " ";
}
return 0;
}
Java
// Java Program to find the next permutation by generating
// all permutations
import java.util.*;
class GfG {
// Find next permutation
static void nextPermutation(int[] arr) {
List<int[]> res = new ArrayList<>();
permutations(res, arr, 0);
Collections.sort(res, Arrays::compare);
// Traverse to find next permutation
for (int i = 0; i < res.size(); i++) {
// Found a match
if (Arrays.equals(res.get(i), arr)) {
// Store the next in arr
if (i < res.size() - 1) {
int[] nextPerm = res.get(i + 1);
for(int j = 0; j < arr.length; j++)
arr[j] = nextPerm[j];
}
// If the given permutation is the last
if (i == res.size() - 1) {
int[] nextPerm = res.get(0);
for(int j = 0; j < arr.length; j++)
arr[j] = nextPerm[j];
}
break;
}
}
}
// Generate permutations recursively
static void permutations(List<int[]> res, int[] arr, int idx) {
// Base case: if idx reaches the end of the array
if (idx == arr.length - 1) {
res.add(arr.clone());
return;
}
// Permutations made by swapping each element
// starting from index `idx`
for (int i = idx; i < arr.length; i++) {
// Swapping
swap(arr, idx, i);
// Recursive call to create permutations
// for the next element
permutations(res, arr, idx + 1);
// Backtracking
swap(arr, idx, i);
}
}
// Swap function
static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {2, 4, 1, 7, 5, 0};
nextPermutation(arr);
for (int num : arr)
System.out.print(num + " ");
}
}
Python
# Python Program to find the next permutation by generating
# all permutations
# Generates all permutations
def permutations(res, arr, idx):
# Base case: if idx reaches the end of the list
if idx == len(arr) - 1:
res.append(arr[:])
return
# Generate permutations by swapping each
# element starting from index `idx`
for i in range(idx, len(arr)):
# Swapping
arr[idx], arr[i] = arr[i], arr[idx]
# Recursive call to create permutations
# for the next element
permutations(res, arr, idx + 1)
# Backtracking
arr[idx], arr[i] = arr[i], arr[idx]
def next_permutation(arr):
# Begin with the smallest permutation
curr = arr[:]
# Generate all permutations and store in res
res = []
permutations(res, curr, 0)
res.sort()
# Traverse through res and print the next permutation
for i in range(len(res)):
# Found a match
if res[i] == arr:
# Print next
if i < len(res) - 1:
arr[:] = res[i + 1]
else:
# If the given permutation is
# the last
arr[:] = res[0]
break
if __name__ == "__main__":
arr = [2, 4, 1, 7, 5, 0]
next_permutation(arr)
print(" ".join(map(str, arr)))
Time Complexity: O(n!*n*log(n!)), n represents the number of elements present in the input sequence represent all possible permutation.
Auxiliary Space: O(n!), for storing the permutations
[Expected Approach] Generating Only Next - O(n) Time and O(1) Space
Let's try some examples to see if we can recognize some patterns.
[1, 2, 3, 4, 5]: next is [1, 2, 3, 5, 4]
Observation: 4 moves and 5 comes in place of it
[1, 2, 3, 5, 4]: next is [1, 2, 4, 3, 5]
Observation: 3 moves, 4 comes in place of it. 3 comes before 5 (mainly 3 and 5 are in sorted order)
[1, 2, 3, 6, 5, 4]: next is [1, 2, 4, 3, 5, 6]
Observation: 3 moves, 4 comes in place of it. [3, 5 and 6 are placed in sorted order]
[3, 2, 1]: next is [1, 2, 3]
Observation: All elements are reverse sorted. Result is whole array sorted.
[1, 2, 3, 6, 4, 5]: next is [1, 2, 3, 6, 5, 4]
Observation: 4 moves and 5 comes in place of it
Observations of Next permutation:
- To get the next permutation we change the number in a position which is as right as possible.
- The first number to be moved is the rightmost number smaller than its next.
- The number to come in-place is the rightmost greater number on right side of the pivot.
Each permutation (except the very first) has an increasing suffix. Now if we change the pattern from the pivot point (where the increasing suffix breaks) to its next possible lexicographic representation we will get the next greater permutation.
To understand how to change the pattern from pivot, see the below image:
Follow the steps below to implement the above observation:
- Iterate over the given array from end and find the first index (pivot) which doesn't follow property of non-increasing suffix, (i.e, arr[i] < arr[i + 1]).
- If pivot index does not exist, then the given sequence in the array is the largest as possible. So, reverse the complete array. For example, for [3, 2, 1], the output would be [1, 2, 3]
- Otherwise, Iterate the array from the end and find for the successor (rightmost greater element) of pivot in suffix.
- Swap the pivot and successor
- Minimize the suffix part by reversing the array from pivot + 1 till n.
C++
// C++ Program to find the next permutation by
// generating only next
#include <bits/stdc++.h>
using namespace std;
void nextPermutation(vector<int> &arr) {
int n = arr.size();
// Find the pivot index
int pivot = -1;
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
pivot = i;
break;
}
}
// If pivot point does not exist, reverse the
// whole array
if (pivot == -1) {
reverse(arr.begin(), arr.end());
return;
}
// find the element from the right that
// is greater than pivot
for (int i = n - 1; i > pivot; i--) {
if (arr[i] > arr[pivot]) {
swap(arr[i], arr[pivot]);
break;
}
}
// Reverse the elements from pivot + 1 to the
// end to get the next permutation
reverse(arr.begin() + pivot + 1, arr.end());
}
int main()
{
vector<int> arr = { 2, 4, 1, 7, 5, 0 };
nextPermutation(arr);
for (int x : arr)
cout << x << " ";
return 0;
}
C
// C Program to find the next permutation by
// generating only next
#include <stdio.h>
#include <stdlib.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void reverse(int arr[], int start, int end) {
while (start < end) {
swap(&arr[start], &arr[end]);
start++;
end--;
}
}
void nextPermutation(int *arr, int n) {
// Find the pivot index
int pivot = -1;
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
pivot = i;
break;
}
}
// If pivot point does not exist,
// reverse the whole array
if (pivot == -1) {
reverse(arr, 0, n - 1);
return;
}
// Find the element from the right that
// is greater than pivot
for (int i = n - 1; i > pivot; i--) {
if (arr[i] > arr[pivot]) {
swap(&arr[i], &arr[pivot]);
break;
}
}
// Reverse the elements from pivot + 1 to the end
reverse(arr, pivot + 1, n - 1);
}
int main() {
int arr[] = { 2, 4, 1, 7, 5, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
nextPermutation(arr, n);
// Print the result
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
Java
// Java Program to find the next permutation by
// generating only next
import java.util.Arrays;
class GfG {
static void nextPermutation(int[] arr) {
int n = arr.length;
// Find the pivot index
int pivot = -1;
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
pivot = i;
break;
}
}
// If pivot point does not exist, reverse the whole array
if (pivot == -1) {
reverse(arr, 0, n - 1);
return ;
}
// Find the element from the right that is greater than pivot
for (int i = n - 1; i > pivot; i--) {
if (arr[i] > arr[pivot]) {
swap(arr, i, pivot);
break;
}
}
// Reverse the elements from pivot + 1 to the end
reverse(arr, pivot + 1, n - 1);
}
// Helper method to reverse array
private static void reverse(int[] arr, int start, int end) {
while (start < end) {
swap(arr, start++, end--);
}
}
// Helper method to swap two elements
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = { 2, 4, 1, 7, 5, 0 };
nextPermutation(arr);
for(int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
}
Python
# Python Program to find the next permutation by
# generating only next
def next_permutation(arr):
n = len(arr)
# Find the pivot index
pivot = -1
for i in range(n - 2, -1, -1):
if arr[i] < arr[i + 1]:
pivot = i
break
# If pivot point does not exist,
# reverse the whole array
if pivot == -1:
arr.reverse()
return
# Find the element from the right
# that is greater than pivot
for i in range(n - 1, pivot, -1):
if arr[i] > arr[pivot]:
arr[i], arr[pivot] = arr[pivot], arr[i]
break
# Reverse the elements from pivot + 1 to the end in place
left, right = pivot + 1, n - 1
while left < right:
arr[left], arr[right] = arr[right], arr[left]
left += 1
right -= 1
arr = [ 2, 4, 1, 7, 5, 0 ]
next_permutation(arr)
print(" ".join(map(str, arr)))
C#
// C# Program to find the next permutation by
// generating only next
using System;
class GfG {
static void NextPermutation(int[] arr) {
int n = arr.Length;
// Find the pivot index
int pivot = -1;
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
pivot = i;
break;
}
}
// If pivot point does not exist, reverse the
// whole array
if (pivot == -1) {
Array.Reverse(arr);
return;
}
// Find the element from the right that
// is greater than pivot
for (int i = n - 1; i > pivot; i--) {
if (arr[i] > arr[pivot]) {
int temp = arr[i];
arr[i] = arr[pivot];
arr[pivot] = temp;
break;
}
}
// Reverse the elements from pivot + 1 to the
// end to get the next permutation
Array.Reverse(arr, pivot + 1, n - pivot - 1);
}
static void Main() {
int[] arr = { 2, 4, 1, 7, 5, 0 };
NextPermutation(arr);
foreach (int x in arr) {
Console.Write(x + " ");
}
}
}
JavaScript
// JavaScript Program to find the next permutation by
// generating only next
function nextPermutation(arr) {
const n = arr.length;
// Find the pivot index
let pivot = -1;
for (let i = n - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
pivot = i;
break;
}
}
// If pivot point does not exist, reverse the
// whole array
if (pivot === -1) {
arr.reverse();
return;
}
// find the element from the right that
// is greater than pivot
for (let i = n - 1; i > pivot; i--) {
if (arr[i] > arr[pivot]) {
[arr[i], arr[pivot]] = [arr[pivot], arr[i]];
break;
}
}
// Reverse the elements from pivot + 1 to the
// end to get the next permutation in place
let left = pivot + 1;
let right = n - 1;
while (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
}
const arr = [2, 4, 1, 7, 5, 0];
nextPermutation(arr);
console.log(arr.join(" "));
Time Complexity: O(n), where n is the size of the given array.
Auxiliary Space: O(1), The algorithm performs in-place operations (modifying the array directly) without using extra space proportional to the input size.
Using C++ in-built function
C++ provides an in-built function called next_permutation(), that return directly lexicographically in the next greater permutation of the input.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> arr = { 2,4,1,7,5,0 };
next_permutation(arr.begin(), arr.end());
for (int num : arr)
cout << num << " ";
return 0;
}
Time Complexity: O(n), as all operations are linear with respect to the array's size.
Auxiliary Space: O(1), The algorithm performs in-place operations (modifying the array directly) without using extra space proportional to the input size
Similar Reads
Permutation
In Mathematics, Permutation is defined as a mathematical concept that determines the number of possible arrangements for a specific set of elements. therefore, it plays a big role in computer science, cryptography, and operations research. For example, take a set {1, 2, 3}:All Permutations taking al
15+ min read
K difference permutation
Given two integers n and k. Consider first permutation of natural n numbers, P = "1 2 3 ... n", print a permutation "Result" such that abs(Resulti - Pi) = k where Pi denotes the position of i in permutation P. The value of Pi varies from 1 to n. If there are multiple possible results, then print the
8 min read
Permutation Formula
Permutation is a fundamental concept in mathematics that deals with arranging a set of objects in a specific order. It focuses on the different ways items can be ordered when the arrangement matters. Permutations are widely used in various fields, including probability, computer science, and data an
6 min read
Permutations and Combinations
Permutation and Combination are the most fundamental concepts in mathematics related to picking items from a group or set. Permutation is arranging items considering the order of selection from a certain group.Combination is selecting items without considering order.For example, in the below diagram
14 min read
CSES Solutions - Permutations
A permutation of integers 1,2 ... N is called beautiful if there are no adjacent elements whose difference is 1. Given N, construct a beautiful permutation if such a permutation exists. If there are no solutions, print "NO SOLUTION".Examples:Input: N = 5Output: 4 2 5 3 1Explanation: No two adjacent
6 min read
Count Permutations in a Sequence
Given an array A consisting of N positive integers, find the total number of subsequences of the given array such that the chosen subsequence represents a permutation. Note: Sequence A is a subsequence of B if A can be obtained from B by deleting some(possibly, zero) elements without changing its or
5 min read
What is Restricted Permutation?
Ans: Restricted permutation is the arrangement of elements made under certain restrictions. In restricted permutations, certain elements are always either included or excluded. Restricted PermutationsThe permutation is a way of filtering and selecting a set of objects, where the arrangement of objec
4 min read
Generate all permutation of a set in Python
Generating all permutations of a set in Python involves creating every possible ordered arrangement of its elements. Since sets are unordered collections, the first step is usually converting the set to a list to maintain a consistent order. For example, given the set {1, 2, 3}, the permutations inc
3 min read
Non-Repeating Bitwise OR Permutation
Given an integer N (N >= 3). Then the task is to output a permutation such that the bitwise OR of the previous two elements is not equal to the current element, given that the previous two element exists. Note: If multiple permutation exists, just print any valid permutation. Examples: Input: N =
3 min read
Heap's Algorithm for generating permutations
Heap's algorithm is used to generate all permutations of n objects. The idea is to generate each permutation from the previous permutation by choosing a pair of elements to interchange, without disturbing the other n-2 elements. Following is the illustration of generating all the permutations of n g
6 min read