leetcode 31. Next Permutation(字典序的下一个)

描述:

  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

字典序:

  对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是 54321。

  那么1234的全排列从小到大的顺序也就是字典序的顺序,依次如下:

    1234,1243,1324,1342,1423,1432,2134,2143,2314,2341,2413,2431,3124,3142,3214,3241,3412,3421,4123,4132,4213,4231,4312,4321

  产生字典序下一个的非递归算法:

    设P是[1,n]的一个全排列,P=P1P2...Pn=P1P2...Pj-1PjPj+1...Pk-1PkPk+1...Pn

    寻找j=max{i|Pi<Pi+1},k=max{i|Pi>Pj},swap Pj和Pk,reverse Pj+1...Pn,得到的P‘=P1P2...Pj-1PkPn...Pk+1PjPk-1...Pj+1,即为P的字典序的下一个排列,当然这里指的是等长度的。

代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int j=-1,k=0,temp,left,right;
        //j=max{i|pi<pi+1}
        for( int i=nums.size()-2;i>=0;i-- ){
            if( nums[i]<nums[i+1] ){
                j=i;break;
            }
        }
        if( j==-1 ){//3 2 1
            sort(nums.begin(),nums.end());
        }else{
            //k=max{i|pi>pj}
            for( int i=nums.size()-1;i>=0;i-- ){
               if( nums[i]>nums[j] ){
                  k=i;break;
                }
            }
            //swap pj pk
            temp=nums[j];nums[j]=nums[k];nums[k]=temp;
            //reverse pj+1 pn
            left=j+1;right=nums.size()-1;
            while( left<right ){
                temp=nums[left];nums[left]=nums[right];nums[right]=temp;
                left++;right--;
           }  
        }
    }
};
原文地址:https://www.cnblogs.com/lucio_yz/p/5219844.html