用示例在Java中实现 next_permutation()
给定一个数组或字符串,任务是找到它在Java中的下一个字典顺序更大的排列。
例子:
Input: string = "gfg"
Output: ggf
Input: arr[] = {1, 2, 3}
Output: {1, 3, 2}
在 C++ 中,有一个特定的函数可以让我们免于编写大量代码。它在头文件#include
显然, Java没有提供任何这样的内置方法。因此,本文讨论如何在Java中实现下一个置换函数及其算法。
天真的方法:生成给定数字/字符串的所有可能排列,将它们存储在一个列表中,然后遍历它以找到给定数字的更大排列。
时间复杂度= O(n!*n) : n!生成所有排列和一个额外的n来遍历并找到更大的排列。
空间复杂度 = O(n!) :存储所有排列。
这种方法非常幼稚且实施起来很复杂。假设我们的数组大小为 100,虽然不是很大,但它会生成 100!排列。这是一个巨大的数字。此外,我们将不得不需要 100 个!存储所有它们的空间,然后遍历它以找到下一个更大的排列。
算法:
这种方法背后的直觉:假设我们有 13542 作为我们的问题,我们必须找到它的下一个排列,观察很明显,当我们从最后一个遍历时,我们看到数字一直在增加,直到 5 和 3 是第一个打破递增顺序的索引,因此,第一步:
- 找到最长的非递增后缀并找到枢轴(3 即索引 1 是枢轴)。
- 如果后缀是整个数组,则数据没有更高阶的排列(在这种情况下,按照问题要求进行操作,返回 -1 或排序后的数组)。
- 找到枢轴的最右边的后继者:再次找到最右边的后继者,从后面开始遍历,当我们遇到大于枢轴的元素时,我们停止,因为它是必需的元素(这里是 4 index=3)。这是有效的,因为当我们从后面遍历时,元素线性增加直到 3(这是数组第一次开始减少)所以,当我们遇到大于 3 的元素时,它确实是更大的元素或后继元素3 并且 4 左边的所有元素(直到 3)都大于 3 并且 4 右边的所有元素都小于 3。
- 交换继任者和支点。
- 后缀反转:一旦我们交换了后继者和枢轴,更高的位置值被修改并更新为更大的值,所以必须清楚只有枢轴之后的元素按升序排列才能获得下一个更大的排列.
下面是上述方法的实现:
Java
// Java program to implement
// the next_permutation method
import java.util.Arrays;
public class nextPermutation {
// Function to swap the data
// present in the left and right indices
public static int[] swap(int data[], int left, int right)
{
// Swap the data
int temp = data[left];
data[left] = data[right];
data[right] = temp;
// Return the updated array
return data;
}
// Function to reverse the sub-array
// starting from left to the right
// both inclusive
public static int[] reverse(int data[], int left, int right)
{
// Reverse the sub-array
while (left < right) {
int temp = data[left];
data[left++] = data[right];
data[right--] = temp;
}
// Return the updated array
return data;
}
// Function to find the next permutation
// of the given integer array
public static boolean findNextPermutation(int data[])
{
// If the given dataset is empty
// or contains only one element
// next_permutation is not possible
if (data.length <= 1)
return false;
int last = data.length - 2;
// find the longest non-increasing suffix
// and find the pivot
while (last >= 0) {
if (data[last] < data[last + 1]) {
break;
}
last--;
}
// If there is no increasing pair
// there is no higher order permutation
if (last < 0)
return false;
int nextGreater = data.length - 1;
// Find the rightmost successor to the pivot
for (int i = data.length - 1; i > last; i--) {
if (data[i] > data[last]) {
nextGreater = i;
break;
}
}
// Swap the successor and the pivot
data = swap(data, nextGreater, last);
// Reverse the suffix
data = reverse(data, last + 1, data.length - 1);
// Return true as the next_permutation is done
return true;
}
// Driver Code
public static void main(String args[])
{
int data[] = { 1, 2, 3 };
if (!findNextPermutation(data))
System.out.println("There is no higher"
+ " order permutation "
+ "for the given data.");
else {
System.out.println(Arrays.toString(data));
}
}
}
[1, 3, 2]