leetcode next-permutation数组排列

实现下一个排列,它将数字重新排列到词典中的下一个更大的数字排列中。
如果这种排列不可能,则必须将其重新排列为尽可能低的顺序(即按升序排序)。
替换必须到位,不要分配额外的内存。
下面是一些例子。输入在左列,相应的输出在右列。
1,2,3→1,3,2
3,2,1→1,2,3
1,1,5→1,5,1

比如第一组的排列从小到大的顺序是
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

第三组
1 1 5
1 5 1
5 1 1

题目要求输出下一组

题解:
下面这种算法据说是STL中的经典算法。在当前序列中,从尾端往前寻找两个相邻升序元素(因为逆序没必要再调转了),升序元素对中的前一个标记为partition。也就是说除了partition,后面的数字都是逆序下降的,也就说以partition开头的最大数字就是现在这组了,partition必须换位置了。
跟谁换呢,跟后面第一个大过他的换。
然后再从尾端寻找另一个大于partition的元素,并与partition指向的元素交换,然后将partition后的元素(不包括partition指向的元素)逆序排列。
比如14532,那么升序对为45,partition指向4,由于partition之后除了5没有比4大的数,所以45交换为54,即15432。
然后将partition之后的元素逆序排列,即432排列为234,则最后输出的next permutation为15234。确实很巧妙。

1 4 6 5 3 2 初始
1 5 6 4 3 2 转换
1 5 2 3 4 6 结果

public class Solution {
    public void nextPermutation(int[] num) {
        int n = num.length;
        int cnt1=-1,tmp;
        if(n==0||n==1) return ;
        for(int i=n-2;i>=0;i--){
            if(num[i]<num[i+1]){
                cnt1 = i;break;
            }
        }
        if(cnt1 != -1){
            for(int i=n-1;i>cnt1;i--){
                if(num[i]>num[cnt1]){//交换
                    tmp = num[cnt1];
                    num[cnt1] = num[i];
                    num[i] = tmp;
                    break;
                }
            }
        }
        
        for(int i=cnt1+1,j=n-1;i<=j;i++,j--){
            tmp = num[i];
            num[i] = num[j];
            num[j] = tmp;
        }
        return ;
    }
}

猜你喜欢

转载自blog.csdn.net/victor_socute/article/details/89481430
今日推荐