求字典序的下一个排列(对应lc的Next Permutation)

如果字典序的下一个排列不存在,则返回升序排序。

步骤如下:

(1)找到排列中最后(最右)一个升序的首位位置i,x = ai。

(2)找到排列中第i位右面比ai大的最右位置j,y = aj。

(3)交换x和y。

(4)把第i+1到数组最后一位的部分旋转。

经过以上4个步骤即可得到下一个排列。

比如当前序列为51432,算法的执行过程为

(1)i = 1,x = 1 。

(2)j = 4,y = 2 。

(3)交换x和y后,得到52431 。

(4)431部分旋转,得到52134 。

下面过程是从组合数学中总结的,说的也是一个意思:

(1) 求满足关系式pj-1<pj的j的最大值,设为i,即
       I=max{ j | pj-1<pj }
(2) 求满足关系式pj-1<pk的k的最大值,记为h
(3) 交换pj-1和ph的值
(4) 从pj开始进行逆序排列


代码中的Qsort函数(快排)其实只用以旋转函数就行。

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if(nums.size()<=1)
			return ;
		if(isDescending(nums)){
			sort(nums.begin(), nums.end());
			return ;
		}
		int j=1, i=0;
		for( ; i<nums.size(); ++i){
			if(nums[i] > nums[i-1])
				j=i;
		}
		int h=j;
		for(i=j; i<nums.size(); ++i) {
			if(nums[i] > nums[j-1])
				h=i;
		}
		swap(nums[j-1], nums[h]);
		int low=j, high=nums.size()-1;
		Qsort(nums, low, high);
	}
private:
	void Qsort(vector<int> &nums, int low1, int high1) {
		if(low1 >= high1) 
			return ;
		int low=low1, high=high1;
		int key=nums[low];
		while(low < high) {
			while(low<high && nums[high]>=key)
				--high;
			nums[low]=nums[high];
			while(low<high && nums[low]<=key)
				++low;
			nums[high]=nums[low];

		}
		nums[low]=key;
		Qsort(nums, low1, low-1);
		Qsort(nums, low+1, high1);
	}
	bool isDescending(vector<int> &nums) {
		int i=0;
		for(i=1; i<nums.size(); ++i) {
			if(nums[i] > nums[i-1])
				return false;
		}
		return true;
	}
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值