LintCode 52-下一个排列

来源:互联网 发布:淘宝如何查看收藏宝贝 编辑:程序博客网 时间:2024/04/30 12:54

本人电子系,只为一学生。心喜计算机,小编以怡情。


给定一个整数数组来表示排列,找出其之后的一个排列。

注意事项

排列中可能包含重复的整数

样例
给出排列[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;    }
0 0