Hướng dẫn next permutation leetcode python

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 print the lexicographically smallest permutation of the given array.

Examples:

Input: N = 6, arr = {1, 2, 3, 6, 5, 4}
Output: {1, 2, 4, 3, 5, 6}
Explanation: The next permutation of the given array is {1, 2, 4, 3, 5, 6}.

Input: N = 3, arr = {3, 2, 1}
Output: {1, 2, 3}
Explanation: As arr[] is the last permutation. 
So, the next permutation is the lowest one.

Brute Force Approach :

A simple way to solve this problem is to generate all the permutations of the given array and return the permutation which is just greater than the given array. 

Time Complexity: O(N * N!), as the total possible permutations are N!
Auxiliary Space: O(N), for storing the permutation in some data structure.

Next Permutation in linear time complexity:

Illustration: 

Let’s try some examples to see if we can recognize some patterns. 

[3, 1, 3] = next greater number is 331
[5, 1, 3] = next greater number is 531
[1, 2, 3] = next greater number is 132
[1, 3, 5, 4] = next greater number is 1435
[3, 2, 1] = we can’t form a number greater than the current number from all the possible permutations

So, it is clear that to get the next permutation we will have to change the number in a position which is as right as possible. Each permutation (except the very first) has a 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:

Observation of Next permutation: 

Illustration of next_permutation

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]).
  • Check if pivot index does not exist 
    • This means that the given sequence in the array is the largest as possible. So, swap the complete array.
  • Otherwise, Iterate the array from the end and find for the successor of pivot in suffix.
  • Swap the pivot and successor
  • Minimize the suffix part by reversing the array from pivot + 1 till N.

Below is the implementation of the above approach:

C++

#include

using namespace std;

void nextPermutation(vector<int>& arr)

{

    int n = arr.size(), i, j;

    for (i = n - 2; i >= 0; i--) {

        if (arr[i] < arr[i + 1]) {

            break;

        }

    }

    if (i < 0) {

        reverse(arr.begin(), arr.end());

    }

    else {

        for (j = n - 1; j > i; j--) {

            if (arr[j] > arr[i]) {

                break;

            }

        }

        swap(arr[i], arr[j]);

        reverse(arr.begin() + i + 1, arr.end());

    }

}

int main()

{

    vector<int> arr = { 1, 2, 3, 6, 5, 4 };

    nextPermutation(arr);

    for (auto i : arr) {

        cout << i << " ";

    }

    return 0;

}

Time Complexity: O(N), where N is the size of the given array.
Auxiliary Space: O(1)