本人电子系,只为一学生。心喜计算机,小编以怡情。
给定一个整数数组来表示排列,找出其之后的一个排列。
注意事项
排列中可能包含重复的整数
样例
给出排列[1,3,2,3],其下一个排列是[1,3,3,2]
给出排列[4,3,2,1],其下一个排列是[1,2,3,4]
思路是,先写出几个常见的找到规律
比如:
123
132
213
231
312
321
从后往前看,发现是23—32,132时,发现前面1位置改变了,1和后面的关系是什么呢?
13是升序,32是降序,找到降序前的那个数字(本题是1),然后将此数字与后面降序数组比较,找到略大于它的那个数字并交换位置。然后对 降序部分 进行排序
拿1432举例,从后往前看,降序前的那个数字是1,1与后面的略大于的数字2交换位置,变成1431,然后对降序部分431进行排序,变成2134,正是我们想要的。
本题技巧:本程序肯定很大,可以将各个功能携程子函数,无论是调试还是其他都会很有帮助。
PS:自己写一遍程序时肯定会遇到相同数字如121等测试数据报错,要自己慢慢debug,这样才有趣~
public int[] nextPermutation(int[] nums) {
// write your code here
//以1432为例
int m=findindex(nums);//找到1的下标
int []temp=Arrays.copyOfRange(nums, m+1, nums.length);//得到子数组432
int n=findanotherindex(temp,nums[m]);//找到略大于的子数组下标,例如2的下标为2
swap(nums, m, n+m+1);//交换两者位置,注意后一个参数
//以为的到是子数组位置,要加上偏移量m,才是nums中的位置
Arrays.sort(nums, m+1, nums.length);//交换后排序成为2134
return nums;//返回答案
}
//找到 1 的下标
static public int findindex( int nums[])
{
int i=nums.length-1;
for(;i>=1;i--)
{
if(nums[i]>nums[i-1]) break;
}
if(i==0)return 0;
return i-1;
}
//得到 2 的下标
public static int findanotherindex(int[] temp,int value) {
int min=Integer.MAX_VALUE;
int index=0;
int flag=0;
for(int i=0;i<temp.length;i++)
{
if(temp[i]-value>0&&min>temp[i]-value)//注意这里的>而不是>=,解决重复的问题
{
min=temp[i]-value;
index=i;
flag=1;
}
}
if(flag==0) return temp.length-1;
return index;
}
//交换程序
static public void swap(int nums[],int start,int end)
{
int temp=nums[start];
nums[start]=nums[end];
nums[end]=temp;
}