Next Permutation

题目要求:从当前排列生成字典序刚好比它大的下一个排列

思路:

1. 如果一个数右边有比它大的数,那么它就能增大。又因为要寻找刚好比当前值大的下一个排列,所以要先寻找最后一个能增大的数A,其位置为i(位置最低)

2. 使A增大为它右边比它大的最小的数B,交换A和B(如果A右边有多个B,则取位置最低的B)

3. 翻转i后面的数字,使其成增序排列

4. 如果没有找到可以增大的数字,说明当前值已为所有排列的最大值,即一个降序排列,因此按照题目要求直接进行翻转即可

代码如下:

class Solution {
public:
    void reverse(vector<int>& nums, int l, int r)
    {
        while(l<r)
        {
            int temp=nums[l];
            nums[l++]=nums[r];
            nums[r--]=temp;
        }
    }
    void nextPermutation(vector<int>& nums) {
        int place=-1;
        for(int i=0;i<nums.size()-1;i++)
        {
            if(nums[i]<nums[i+1])
                place=i;
        }
        if(place==-1)
            reverse(nums,0,nums.size()-1);
        else
        {
            int i=place+1;
            int large=place+1;
            while(i<nums.size()-1)
            {
                if(nums[i+1]<=nums[i]&&nums[i+1]>nums[place])  //注意此处条件为小于等于
                    large=i+1;
                i++;
            }
            int temp=nums[place];
            nums[place]=nums[large];
            nums[large]=temp;
            reverse(nums,place+1,nums.size()-1);
        }
            
    }
};

由于第一步和第二步都是找位置最低的数,所以更好的方式是从后往前寻找,更新代码如下:

class Solution {
public:
    void reverse(vector<int>& nums, int l, int r)
    {
        while(l<r)
        {
            int temp=nums[l];
            nums[l++]=nums[r];
            nums[r--]=temp;
        }
    }
    void nextPermutation(vector<int>& nums) {
        int place=nums.size()-2;
        while(place>=0 && nums[place]>=nums[place+1])
            place--;
        if(place<0)
            reverse(nums,0,nums.size()-1);
        else
        {
            int large=nums.size()-1;
            while(nums[place]>=nums[large])
                large--;
            int temp=nums[place];
            nums[place]=nums[large];
            nums[large]=temp;
            reverse(nums,place+1,nums.size()-1);
        }
            
    }
};

 

posted on 2016-05-31 20:27  summerkiki  阅读(192)  评论(0编辑  收藏  举报