LeetCode 31. 下一个排列(C++)

题目描述

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

思路

这一题也是属于那种暴力法实施起来很困难,并且难想到其他解决方法的题目,这题的突破点是从右到左遍历数组找到nums[i]>nums[i-1]这样的位置i,因为像[3,2,1,0]这样的数组是无法找到下一个排列的;然后再从位置i从左往右遍历找到nums[i-1]>=nums[j]的这样一个位置j;swap调换nums[i-1]和nums[j-1]的位置后reverse倒置从i开始的元素,需要注意的是如果判断已经找不到下一个排列则直接反转数组
官方解答:https://leetcode-cn.com/problems/next-permutation/solution/

代码

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if(nums.size()<=1) return ;
        int i,j;
        for(i=nums.size()-2;i>=0;i--)
        {
            if(nums.at(i)<nums.at(i+1)) break;
        }
        if(i<0) reverse(nums,0,nums.size()-1);
        else
        {
            for(j=nums.size()-1;j>i;j--)
            {
                if(nums.at(j)>nums.at(i)) break;
            }
            swap(nums,i,j);
            reverse(nums,i+1,nums.size()-1);
        }
    }
    void swap(vector<int>& nums,int i,int j)
    {
        int temp=nums.at(j);
        nums.at(j)=nums.at(i);
        nums.at(i)=temp;
    }
    void reverse(vector<int>& nums,int i,int j)
    {
        while(i<j)
        {
            swap(nums,i,j);
            i++;
            j--;
        }
    }
};

你可能感兴趣的:(LeetCode 31. 下一个排列(C++))