zoukankan      html  css  js  c++  java
  • 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--;
               }  
            }
        }
    };
  • 相关阅读:
    网络编程
    反射函数与元类
    面向对象进阶
    对象的封装与接口
    对象继承
    面向对象
    包,logging模块与haslib模块
    闭包函数及装饰器
    函数对象、函数的嵌套、名称空间及作用域
    函数简介及函数参数介绍
  • 原文地址:https://www.cnblogs.com/lucio_yz/p/5219844.html
Copyright © 2011-2022 走看看