LeetCode 31. Next Permutation

问题链接

LeetCode 31. Next Permutation

题目解析

求序列的下一个字典序列。

解题思路

什么是下一个字典序列?了解一下:next_permutation(全排列算法)。算法的核心思想:

  • 从序列尾部开始往前寻找两个相邻元素,设为(i,ii),即有 \(\*i < \*ii\)
  • 再次从序列尾部往前寻找第一个大于 *i 的元素,设为 *j,即有 \(\*j > \*i\)。交换(*i,*j)。
  • 将从 *ii 开始在尾部的所有元素逆序排列。

//注:第二第三步可交换,即先全部逆序,再找两个交换也OK,不过在找 *j 时需要正序从 *i++ 开始找。

本题的目的应该是要实现该算法,看过描述后可以直接写出代码。

一行代码

如果只是这样的话,那就没什么意思了:)放在这里只是告诉大家C++中有这么一个函数,对了还有一个与之配套的函数,叫做prev_permutation,没错它是用来求上一个排列的。

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        next_permutation(nums.begin(), nums.end());
    }
};

具体实现

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int i, j, n = nums.size();
        for(i = n - 2; i >= 0; i--) {
            if (nums[i + 1] > nums[i]) {
                for(j = n - 1; j > i; j--) {
                    if (nums[j] > nums[i]) break;
                }
                swap(nums[i], nums[j]);
                reverse(nums.begin() + i + 1, nums.end());
                return;
            }
        }
        reverse(nums.begin(), nums.end());//全部逆序排列
    }
};

当然,想要具体再把swap和revese函数实现也可以,可参考Next Permutation。我认为重点理解如何求解下一个序列的方法就OK,没有必要太过深入。另外,上述代码可以稍微简化一下,道理是一样的,代码如下:

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

相似题目


LeetCode All in One题解汇总(持续更新中...)

本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


posted @ 2018-03-29 22:50  AlvinZH  阅读(287)  评论(0编辑  收藏  举报