1.题目
给定一个整数数组来表示排列,找出其之后的一个排列。
给出排列[1,3,2,3]
,其下一个排列是[1,3,3,2]
给出排列[4,3,2,1]
,其下一个排列是[1,2,3,4]
2.算法
《STL源码剖析》中是这样写的
在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
public void nextPermutation(int[] nums)
{
if (nums == null || nums.length == 0)
{
return null;
}
int i = nums.length - 2;
while (i >= 0 && nums[i] > nums[i + 1]) //从后往前找第一个不是反序数字p
{
i--;
}
if (i >= 0) //找到后,从前往后找找到下一个数就比p对应的数小的数字
{
int j = i + 1;
while (j < nums.length && nums[i] < nums[j])//即使最后一个没有小于p,那就是最后一个
{
j++;
}
j--;//找到之后交换位置
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
reverse(nums, i+1); //反转
}
public void reverse(int[] num, int index)
{
int l = index;
int r = num.length;
while (l < r)
{
int temp = num[l];
num[l] = num[r];
num[r] = temp;
l++;
r--;
}
}
这道题目我的解题步骤是
1.从后往前扫描找到第一个不是反序的数组下标p,如果p=-1,直接反序数组,否则记下p
2.从p向后扫描,找到第一个不大于p在数组中数的,记它前面下标q,如果都大于,则记q为最后一个元素,交换p和q的位置。
3.反序从p后面数组