Next Permutation:已知某个排列求下个排列

来源:互联网 发布:怎样成为一个网络写手 编辑:程序博客网 时间:2024/05/29 19:26

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1


思路:属于读不懂题,一脸懵13然后AC的那种。

“解释一下排列规律,类比于加法进位,只不过每一位可用数字有限。

如2399,是所有排列里最小的那个,下一个排列应当是刚好大于它且小于其他排列。按照此思路,最后两位都是“加满“状态,即“个位”、“十位”。所谓“加满”指从右往左扫描为非递减序列。需要“加一进位”,所以“百位”需要增大,而“百位”的3“加一进位”应当为9,所谓“加一进位”即从左往右寻找刚好大于的位置对应的元素,而进位后“个位”、“十位”应该变为“减空状态”,所谓“减空”指从左往右为非降序序列,下一排列即为2939。”----啰嗦一堆,不看也罢O(∩_∩)O

上面只是一个类比,思路是:对于数组nums[],

1.从后向前扫描找到第一个大小下降的位置x,对应2399里的3;

2.从x位置向后扫描,直至该位置y的值nums[y]大于nums[x]且该位置的下一位置y+1的值nums[y+1]不大于nums[x],若没找到就更高最后一个位置,即y=nums.length-1;

如2399里的x=1,y=3

3.交换下标x、y元素

如2399变为2993

4.将x位置后的所有元素逆序

如2399变为2993后,x后的元素为93,逆序为39,最后结果即为2939

class Solution {    public void nextPermutation(int[] nums) {        if(nums.length<=1) return;        int n = nums.length;        int x = n-2;        while(x>=0){            if(nums[x]>=nums[x+1]){                x--;            }else{                break;            }        }        if(x>=0){            int y = x+1;            while(y<n){                if(nums[y]<=nums[x]) break;                y++;            }            y--;            int t = nums[x];            nums[x] = nums[y];            nums[y] = t;              }                reverse(nums,x+1);    }        public void reverse(int[] nums,int index){        int t;        int l = index;        int r = nums.length-1;        while(l<r){            t = nums[l];            nums[l] = nums[r];            nums[r] = t;            l++;            r--;        }    }}

解释的有点乱,回头我在组织一下语言,尴尬


原创粉丝点击