leetcode9:Next Permutation

Next Permutation 

题目链接:https://oj.leetcode.com/problems/next-permutation/

runtimes:17ms


一、问题

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, do not allocate 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

二、分析

        什么是Next Permutation ?其实一开始看很难理解,但是后来看了STL源码剖析就明白了。next permutation 其实就是求序列的下一个字典排序,要求是上个排序要比下个排序要小,并且之间不存在其他排序序列。举个实例,比如序列abc,显然abc就是第一个字典排序序列,而abc的next permutation 是acb,为什么呢?因为以a为开头的序列还有acb,如果此时改换成b、c开头,与abc中间还有a开头的序列,因此确定a为下个序列的首位,那么剩下bc交换位置即可,就是acb;而acb的下个字典排序序列是以b开头,其中bac < bca,因此可得bac是下个字典排序序列,bca是bac的下个字典排序;而bca的下个字典排序序列以c开头,同样可得cab、cba两个序列。

        通过以上分析,我们就可以得到两点,其一,下个字典序列要和上个字典要有尽可能长的共同前缀,其二,从后面往前扫描进而改变,酱紫能使两个序列之间的差更小。举另外一个例子的推演过程,{0, 1, 2, 3, 4},其中红色代表这个序列到下个序列将要变化的部分。

       {0, 1, 2, 3,4}  →  {0, 1, 2, 4,3}  →  {0, 1, 3, 2,4}  →  {0, 1, 3, 4,2}  →  {0, 1, 4, 2,3}  →  {0, 1, 4, 3,2}  →  {0, 2, 1, 3,4}  → ……

       想知道具体变化步骤是什么?看小结呗~

三、小结

       设数组A为序列,共有n个元素:

       1、首先从后往前扫面,找到第一个A[i - 1] < A[i]的元素位置i;

       2、接着从后往前扫描,找到第一个A[j] > A[i - 1]的元素位置j,交换A[i - 1]和A[j],对A[i]到A[n - 1]之间的元素升序排列;

       3、重复1、2,直到序列为降序序列位置。

       ps:从题目可以看出,最后一个序列的下一个字典序列是第一个序列,即cba的下一个字典序列是abc。

四、实现

#include <algorithm>
class Solution {
public:
    void nextPermutation(vector<int> &num) {
        bool flag = false;
        for(int i = num.size() - 1; i > 0; i--)
        {
            if(num[i - 1] < num[i])
            {
                flag = true;
                for(int j = num.size() - 1; j > i - 1; j--)
                {
                    if(num[i - 1] < num[j])
                    {
                        int temp = num[i - 1];
                        num[i - 1] = num[j];
                        num[j] = temp;
                        break;
                    }
                }
                sort(num.begin() + i, num.end());
                //i = num.size();
                break;
            }
        }
        if(!flag)
        {
            for(int i = 0, j = num.size() - 1; i < j; i++, j--)
            {
                int temp = num[j];
                num[j] = num[i];
                num[i] = temp;
            }
        }
    }
};



五、三思

        get新技能,可以了解一下STL中Next Permutation 的实现。推荐一篇不错的文章,不过还是没有我讲的清楚啦~

        原文链接:http://blog.csdn.net/m6830098/article/details/17291259

       以下也给出全排列的实现:

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
	void nextPermutation(vector<int> &num) {
		for (int i = num.size() - 1; i > 0; i--)
		{
			if (num[i - 1] < num[i])
			{
				for (int j = num.size() - 1; j > i - 1; j--)
				{
					if (num[i - 1] < num[j])
					{
						int temp = num[i - 1];
						num[i - 1] = num[j];
						num[j] = temp;
						break;
					}
				}
				sort(num.begin() + i, num.end());
				i = num.size();
				for (int k = 0; k < num.size(); k++)
				{
					cout << num[k] << " ";
				}
				cout << endl;
			}
		}
	}
};

int main(int argc, char **argv[])
{
	vector <int> p = {0, 1, 2, 3, 4};
	Solution s;
	s.nextPermutation(p);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值