leetcode题解:下一个排列

题目描述

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

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

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

来源:力扣(LeetCode)

 题目分析

字典序排列,只允许使用常数空间。最初思路即为建立字典树,进行遍历,但时间内存超限不可行

题解:学习(powcai)大神的思路

字典序的排列,是从最后往前的变动,因此选择从后往前查找,具体操作为:

1、先找出最大的索引 k 满足 nums[k] < nums[k+1],如果不存在,就翻转整个数组;
2、再找出另一个最大索引 l 满足 nums[l] > nums[k];
3、交换 nums[l] 和 nums[k];
4、最后翻转 nums[k+1:]。

void nextPermutation(vector<int>& nums) {
        cout<<endl;
        int len, i, j, tmp;
        len = nums.size();
        if(len <= 1) return;

        // 首先查找到第一个nums[k] < nums[k+1]的位置
        for(i = len - 2; (i>= 0)&&(nums[i] >= nums[i+1]); i--);

        // 若i<0,表示遍历至头部,直接翻转整个vector
        if (i < 0){
            // 采用sort进行从小到大的排序,来实现翻转
            sort(nums.begin(), nums.end());
            return;
        }

        // 从后往前找到第一个大于nums[i]的位置
        for(j = nums.size()-1; nums[j]<=nums[i];j--);

        // 交换两个值
        tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp;
        // 对i之后的值进行排序
        sort(nums.begin() + i + 1, nums.end());
        return;
    }

猜你喜欢

转载自blog.csdn.net/li6016265/article/details/112797818