LeetCode算法系列:31. Next Permutation

版权声明:由于一些问题,理论类博客放到了blogger上,希望各位看官莅临指教https://efanbh.blogspot.com/;本文为博主原创文章,转载请注明本文来源 https://blog.csdn.net/wyf826459/article/details/82117538

目录

 

题目描述:

题目重新描述:

算法描述:

算法实现


题目描述:

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

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.

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

题目重新描述:

这里涉及到了一个概念就是全排列的概念

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。
当m=n时所有的排列情况叫全排列。

例如对1,2,3,4的全排列共24种,为

1,2,3,4
1,2,4,3
1,3,2,4
1,3,4,2
1,4,2,3
1,4,3,2
2,1,3,4
2,1,4,3
... ...
4,1,2,3
4,1,3,2
4,2,1,3
4,2,3,1
4,3,1,2
4,3,2,1

这个问题的意思是求当前一种全排列的后一种,如上1,4,3,2的后一种是2,1,3,4

算法描述:

1,首先我们要先找到一种模式的子串,在其中的数字是逆序排列的,这个子串的长度可以为1

2,我们要找到这个子串前面的元素,在这个序列的下一个序列,这个位置的元素会发生变化。因为这个元素位于这个位置的所有排列已经列举完毕。我们要将这个元素换成后面子串序列中比它大的最小元素,即交换二者的位置。当然如果这个子串已经是全部序列了,那么我们只需要将之逆转就可以结束了

3,我们可以证明,执行2操作后,那一位置后面子串还是逆序排列的,但是改变当前位置元素之后的第一个序列其后应该是正序的,故要将之逆转。

算法实现

class Solution {
public:
    //交换数组nums中i和j位置的元素
    void swap(int i, int j, vector<int>& nums){
        int temp;
        temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    void nextPermutation(vector<int>& nums) {
        int i,j,k;
        //从后向前扫描找到第一个正序排列的位置,在这个位置之后是逆序排列的
        for(i = nums.size() - 1; i > 0; i --)
        {
            if(nums[i] > nums[i - 1])break;
        }
        //如果没有找到这个位置,那么整个数组是逆序排序,那么只需要将整个数组顺序排列(将数组倒过来)即可
        if(i == 0)
        {
            //将数组从0到end的部分倒过来排列
            for(i = 0, k = nums.size() -1; i < k ; i ++, k --)swap(i,k,nums);
            return;
        }
        j = i - 1;
        //如果找到了那个位置(j),只需要将j后面的部分中比j大的最小元素和j交换位置,然后再将后面的元素反序即可
        for(k = nums.size() - 1; k > j; k --)
            if(nums[k] > nums[j])break;
        swap(j,k,nums);
        for(i = j + 1, k = nums.size() -1; i < k ; i ++, k --){
            swap(i,k,nums);
        }
    }
};

猜你喜欢

转载自blog.csdn.net/wyf826459/article/details/82117538