Next Permutation
Problem
Print the next bigger arrangement of the numbers in dictionary order. If the array is already the biggest arrangement, print the smallest one (sorted ascending).
Constraints
- 1 <= n <= 10^5
Examples
Input
3 1 2 3
Output
1 3 2
Input
3 3 2 1
Output
1 2 3
Solutions
The suffix that is in descending order is the biggest arrangement of its values, so it cannot grow. We must raise the pivot just before it by the smallest possible step and then make the suffix as small as possible.
/*
* Problem : Process an array.
* Input : n, then n integers.
* Output : The next arrangement.
* Approach: Find the pivot.
* Time : O(n)
* Space : O(1)
* Java : 8 or newer.
*/
import java.util.Scanner;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int[] solve(int[] a) {
// Step 1: From the right, find the first place i where a[i] < a[i + 1]. The part after i is in descending order.
int i = a.length - 2;
while (i >= 0 && a[i] >= a[i + 1]) {
i--;
}
// Step 2: If such a place exists, swap a[i] with the smallest value on its right that is bigger than a[i].
if (i >= 0) {
int j = a.length - 1;
while (a[j] <= a[i]) {
j--;
}
int temporary = a[i];
a[i] = a[j];
a[j] = temporary;
}
// Step 3: Reverse the part after i. It is now the smallest arrangement of those values.
int left = i + 1;
int right = a.length - 1;
while (left < right) {
int temporary = a[left];
a[left] = a[right];
a[right] = temporary;
left++;
right--;
}
return a;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = scanner.nextInt();
}
System.out.println(Arrays.stream(solve(a)).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
Hints (1)
- Why do we reverse the suffix at the end?