next-permutation(下一个全排列)

https://www.nowcoder.com/practice/f0069cfcd42649e3b6b0c759fae8cde6?tpId=46&tqId=29148&tPage=3&rp=3&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking

思路:从后往前找第一个升序对,将pre指针指向升序对的第一个元素,然后从后往前找第一个大于pre指向的数的数字,然后交换该数字和pre指向的数字。然后将pre后面的数字逆过来

比如 1 2 3 4 0的下一个全排列。从后往前找第一个升序对是(3, 4),从后往前找到第一个大于3的数字是4,即找第一个大于” 前面找到的升序对的第一个元素3 ”的数字。 然后交换3和4得到12430,然后再把升序对后面的数字逆过来,得到12403.即12403就是12340的下一个排列。

class Solution {
public:
    void nextPermutation(vector<int> &num) {
        int n = num.size();
		if(n <= 0)
			return ;

		if(n == 1)//只有一个数字
			return ;

		int pre = n - 2, net = n - 1;//分别升序对的位置

		while(pre >= 0 && num[pre] >= num[net])//从后往前找第一个升序对
		{
			pre--;
			net--;
		}

		if(pre >= 0)//找到升序对
		{
			//从后往前找第一个大于pre的数字并交换
			for(int i = n -1; i != pre; i--)
			{
				if(num[i] > num[pre])
				{
					swap(num[i], num[pre]);
					break;
				}
			}
		
			reverse(num, pre + 1, n - 1);//把pre后的数字顺序颠倒过来

		}
		else
		{
			//从后往前没有找到第一个升序对,说明该数字是最大了。
			//所以没有下一个全排列,按题意直接把数组翻转。
			reverse(num, 0, n - 1);

		}
		

		return ;
    }

	void reverse(vector<int> & num, int start, int end)
	{
		//vector<int>temp;
		int * temp = new int[end - start + 1];
		int p = 0; 
		for(int i = end; i >= start; i--)
			temp[p++] = num[i];
		int j = 0;
		for(int i = start; i <= end; i++)
			num[i] = temp[j++];

		delete []temp;
		
	}
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值