Open In App

JavaScript Program to Find Lexicographically Next Permutation

Given an array of distinct integers, we want to find the lexicographically next permutation of those elements. In simple words, when all the possible permutations of an array are placed in a sorted order, it is the lexicographic order of those permutations. In this case, we have to find the next greater permutation of the elements in this sorted or lexicographic order.

Examples:

Example 1:
Input: [1, 2, 3]
Output: [1, 3, 2]
Explanation:  If all the permutations of these elements are arranged in a sorted order:
[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
Here, next greater permutation of [1, 2, 3] is [1, 3, 2].
Example 2:
Input: [6, 3, 4, 7, 1] Output: [6, 3, 7, 1, 4] Explanation: If all the permutations of these elements are arranged in a sorted order, next greater permutation of [6, 3, 4, 7, 1] is [6, 3, 7, 1, 4].

Approach 1: Brute Force Approach

As a brute force approach, we can generate all the possible permutations of the given array and store all the generated sequences. Then we sort all these arrays in increasing order and find the lexicographically next permutation by a simple searching technique.

Algorithm:

Example: Below is the implementation of the above approach






// JavaScript code for the above approach
  
// Recursive function to generate all permutations 
const permute = (arr, idx, res) => {
  
    // Base case
    if (idx === arr.length - 1) {
        res.push([...arr]);
        return;
    }
  
    const n = arr.length;
  
    // Iterate the array starting from the new index
    for (let i = idx; i < n; i++) {
      
        // Swap the elements
        [arr[idx], arr[i]] = [arr[i], arr[idx]];
          
        // Make a recursive call 
        permute(arr, idx + 1, res);
          
        // Backtrack
        [arr[idx], arr[i]] = [arr[i], arr[idx]];
    }
};
  
// Function to call the recursive function
function generatePermutations(arr) {
    const res = [];
    permute(arr, 0, res);
    return res;
}
  
// Input
let arr = [1, 2, 3];
let total = generatePermutations(arr);
  
const n = total.length;
  
// Sort the permutations' array
total.sort();
  
let ans = null;
  
// Check if the input array is 
// the largest possible permutation
if (JSON.stringify(total[n - 1]) === 
        JSON.stringify(arr)) {
          
    // If yes, then the next permutation 
    // is the smallest permutation
    ans = total[0];
}
  
// Find the next permutation
for (let i = 0; i < n - 1; i++) {
    if (JSON.stringify(total[i]) === 
            JSON.stringify(arr)) {
        ans = total[i + 1];
        break;
    }
}
  
// Print the answer
if (ans) {
    console.log(ans);
}
else {
    console.log("No next permutation found");
}

Output
[ 1, 3, 2 ]

Time Complexity: O(N!*N)

Space Complexity: O(1)

Method 2: Optimal Approach

If we observe the pattern, we find that in all these generated permutations, there exists an index such that the part to its right is decreasingly sorted. On traversing the array backward (from n-1), it is sorted in ascending order till this index i.

Algorithm:

Example: Below is the implementation of the above approach




// Function to find the next permutation 
function nextPermutation(arr) {
    const n = arr.length;
    let idx = -1;
  
    // Find the element from right that 
    // is smaller than its right neighbor
    for (let i = n - 2; i >= 0; i--) {
        if (arr[i] < arr[i + 1]) {
          
            // index i is the element to be swapped
            idx = i;
            break;
        }
    }
  
    // If no such element exists, reverse 
    // it to get the smallest permutation
    if (idx === -1) {
        arr.reverse();
        return arr;
    }
  
    // Find the smallest element as per the above approach
    for (let j = n - 1; j > idx; j--) {
        if (arr[j] > arr[idx]) {
          
            // index j is the element to be swapped
            [arr[j], arr[idx]] = [arr[idx], arr[j]];
            break;
        }
    }
  
    // Reverse the part to the right of arr[i]
    let left = idx + 1;
    let right = n - 1;
    while (left < right) {
        [arr[left], arr[right]] = [arr[right], arr[left]];
        left++;
        right--;
    }
  
    return arr;
}
  
// Input
const arr = [5, 2, 9, 8];
const ans = nextPermutation(arr);
console.log(ans);

Output
[ 5, 8, 2, 9 ]

Time Complexity: O(N)

Space Complexity: O(1)


Article Tags :