上一个排列和下一个排列

下一个排列:

 

思路:

 

1. 先找到需要改变的高位:从右向左扫描排列,若一直满足nums[i] > nums[i - 1],则说明这些元素是满足高位大于低位的,不需操作,直到找到nums[i] < nums[i - 1],找到高位比低位小的了,而且是“最低”的高位,这个位置就是我们需要做交换操作的。比如:6, 8, 7, 4, 3, 2 当中的8(发现6 < 8)

2. 第二步找要和这个高位交换的低位:原则是尽量寻找只比这个高位“大一点”的低位,因为只是下一个排列。因为在这个高位右边的数组满足从右往左递增,所以,我们重新从右边起扫描,找到第一个比这个高位大的元素。比如:6, 8, 7, 4, 3, 2 中的7.

3. 交换高位与低位,使得高位变大:比如6, 8, 7, 4, 3, 2 -> 7, 8, 6, 4, 3, 2

4. 此时,不论交换后的高位后面的元素是如何排列的,都肯定比之前的排列靠后了。因为只是下一个排列,所以我们现在尽量要现在的这个排列“靠前”,怎么做呢,就是按升序排列高位后面的元素,比如:按升序排列此时7后面的元素。因为此时高位后面的元素一定是从左往右,从大到小,所以,也相当于是翻转这一部分的数组。比如:7, 8, 6, 4, 3, 2 -> 7, 2, 3, 4, 6, 8

算法过程如下:

  • 先从后往前找到  i 位置小于 i+1 位置的数,
  • 从后往前找到第一个小于 i 位置 的数, 此数位置为 j
  • 交换 i 和 j 。
  • 逆序

 

上一个排列:

思路:

其实和下一个排列是一样的

1、上一个排列就是所有全排列按照升序排列后的上一个排列

2、如数字排列63624578,其上一个排列为63587642

3、由于是在所有升序排列中找到上一个排列,所以对于某一个排列,我们假设从某一位开始,后面的数字应当都是升序。

4、那我们从右到左找到第一个num[i]大于num[i+1]的位置。再从右到左找到第一个小于num[i]的位置将他们交换。

5、再将从i+1到nums.size()之间的数逆序,即前一个排列。

算法过程如下:

  • 先从后往前找到  i 位置大于 i+1 位置的数,
  • 从后往前找到第一个大于 i 位置 的数, 此数位置为 j
  • 交换 i 和 j 。
  • 逆序

 

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

vector<int> nextPermuation(vector<int>& nums)
{
    int len = nums.size();
    if (len == 0)
        return nums;

    int pos = -1;

    for (int i = len - 2; i >= 0; i--)
    {
        if (nums[i] < nums[i + 1])
        {
            pos = i;
            break;
        }
    }
    if (pos == -1)
    {
        reverse(nums.begin(), nums.end());
        return nums;
    }
    else
    {
        for (int i = len - 1; i > pos; i--)
        {
            if (nums[pos] < nums[i])
            {
                swap(nums[pos], nums[i]);
                reverse(nums.begin() + pos + 1, nums.end());
                break;
            }
        }
    }
    return nums;
}


vector<int> previousPermuation(vector<int>& nums)
{
    int len = nums.size();
    if (len <= 0)
        return nums;

    int pos = -1;

    for (int i = len - 2; i >= 0; i--)
    {
        if (nums[i] > nums[i + 1])
        {
            pos = i;
            break;
        }
    }

    if (pos == -1)
    {
        reverse(nums.begin(), nums.end());
        return nums;
    }
    else
    {
        for (int i = len - 1; i > pos; i--)
        {
            if (nums[pos] > nums[i])
            {
                swap(nums[pos], nums[i]);
                reverse(nums.begin() + pos + 1 , nums.end());
                break;
            }
        }
    }
    return nums;
}

int main()
{
    vector<int> nums = { 2,4,3,5 };
    vector<int> res1,res2;
    res1 = previousPermuation(nums);
    vector<int> nums2 = { 2,3,4,5 };
    res2 = nextPermuation(nums);
    for (auto i : res1)
        cout << i << " ";
    cout << endl;
    for (auto i : res2)
        cout << i << " ";
    cout << endl;
    system("pause");
    return 0;
}

 

 

posted @ 2020-08-08 22:41  r1-12king  阅读(536)  评论(1编辑  收藏  举报