LeetCode 31. Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.html

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 and use only constant extra memory.数组

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.spa

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1code

 

 

解答:htm

题目看似不难,其实仍是颇有门道的,须要求“下一个排列”,如何定义下一个,这个问题有些像“数字大小的排序问题”,假设给定一、二、3三个数字,从小到大来作排列,那显然结果是123,132,213,231,312,321。如今的问题在于,如何厘清算法的流程,假设数组长度为n,数组名为nums,步骤以下:blog

  • 从后往前遍历,找到index为i的数字,知足nums[i] < nums[i-1],若没有则序列为彻底逆序,翻转整个序列
  • 从后往前,遍历[i+1,n-1],找到最大的j知足nums[j] > nums[i]
  • 交换nums[j]和nums[i]
  • 将nums[i+1]~nums[n-1]的全部数字翻转

至于为什么要这么作,个人理解是由于“下一个”,因此要吃透含义,有点相似于数字进位的问题,首先找到一个峰值,接下来寻找比当前的数字大但最接近当前数字的数,因此就有了上面的算法,代码以下:排序

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int len = nums.size(),i,j;
        for (i = len - 2; i >=0; i--)
            if (nums[i] < nums[i + 1])
                break;
        if (i < 0)
            reverse(nums.begin(), nums.end());
        else
        {
            for (j = len - 1; j > i; j--)
                if (nums[j] > nums[i])
                    break;
            swap(nums[j], nums[i]);
            reverse(nums.begin() + i + 1, nums.end());
        }
    }
};

时间复杂度:O(N)ip

空间复杂度:O(1)leetcode

参考连接:

http://www.javashuo.com/article/p-dohdsmzo-ga.html

https://leetcode.com/problems/next-permutation/discuss/13867/C%2B%2B-from-Wikipedia

相关文章
相关标签/搜索