LeetCode 31

这个题目的意思结合所给示例以及题目描述,可以知道。给一个数组,求该数组所组成的数字的全排列的下一个数字,这句话不懂没关系,我举个例子你就懂了

     例如: 

   1.若给的是 1 2 3 ,那么你要将数组内容变为 1 3 2;

   2.若给的是 3 2 1 ,那么i要见数组的内容变为1 2 3;

其实这是一个循环的排列,就是你给任意的数字排列,都可以找到下一个排列,大概就是这样的情况


如上图,假如你给的数字是,123的全排列的中的一个,那么最后的结果将是这个排列的下一个排列,到这里相信大家理解意思了吧。那么下面就说说题目的解法吧:

 1.首先题目不准使用额外的空间,如果可以的话,我们可以求出全排,然后像查表一样就可以了,不过仔细想想这样确实比较低效率,假若所给的数字为100位甚至更多,那么它的全排列将会是多大呢,将会使用很大的空间。

2.这个题目我想了比较长的时间,因为我一看到它的时候就知道,这其实是一个数学规律,只要找到规律了就好办了。我也测试了好几次,然后从错误中找到了规律。规律如下:

   1.极端情况,如: 3 2 1

这种情况就可以直接将数组排序即可   

   2.最喜欢的情况: 1 2 3

        这种情况只需要将2与3互换位置 

   3.平常且难想的情况: 假如给的数组序列为: 5 4 7 5 3 2

 此时我们该如何动手呢?好了,这个时候就是展现真正本领的时候了....

请注意,上面的情况中5 4 7 5 3 2 序列中是蓝色的有序的,即依次降序,可以说明,这个时候5 4 7 5 3 2所组成的数字是最大的(绿色部分),所以下一步是找到比这个数字更大的数字,那么只能往前考虑了,即把4加入到 54 7 5 3 2 中,那么就是 54 7 5 3 2,意思就是找到比5 4 7 5 3 2大的数字中的最小的一个。用肉眼去看,是 55 2 3 4 7 所以我们是找到了比5 4 7 5 3 2 大的数字中的最小的一个,方法是在黄色序列中(7 5 3 2)找到比红色(4)大的数字中最小的一个,然后互换两者的位置 5 57 4 3 2还没完,此时还不是索要找的数字。将蓝色部分排序后 : 5 5 2 3 4 7,这就是慢要求的下一个数字。

到此我们可以开始系代码了,思路是,从后往前找,假设此时pos是最后一个位置,当我们找到pos-1位置比pos位置小的时候停止,那么这个时候pos位置以后的部分时有序的,如:


* 这个时候,再从右边的序列中找到比pos-1位置大的元素,交换两者,然后排序即可。

* 若pos指向 0 了,则说明该情况类似 3 2 1,我们将整个排序即可。

* 若pos的位置还是在最后一个,即 123 的情况,这儿时候交换pos和pos-1的位置即可。

代码:

class Solution {
public:
	void nextPermutation(vector<int>& nums)
	{
		int len = nums.size();
		if (len == 0 || len == 1)
		{
			return;
		}
		//从尾部向前找,找到nums[pos] > nums[pos-1]位置
		int pos = len - 1;
		while (pos > 0 && nums[pos] <= nums[pos - 1])
		{
			--pos;
		}

		if (pos == 0)
		{//说明到了最后一个位置,例如 3 2 1 ,此时将它排序即可
			sort(nums.begin(), nums.end());
			return;
		}
		else
		{
			if (pos == len - 1)
			{//pos 在最后一个位置,例如 1 2 3 ,那么此时将nums[pos]与nums[pos-1]互换即可
				swap(nums[pos], nums[pos - 1]);
				return;
			}
			else
			{ //这种情况说明pos在中间位置,举例吧,如:5 4 7 5 3 2   
				int key = nums[pos - 1];
				//找比key值大的数字,即比4大的数,可以看到是5(后面的5)
				int begin = len - 1;
				while (begin > pos && nums[begin] <= key)
				{
					--begin;
				}
				//此时 begin 位置的数字比 key 值大,因为至少pos位置的数比key值大,而且从pos到len-1之间的数字是降序的
				swap(nums[pos - 1], nums[begin]);
				//swap以后序列为 5 5 7 4 3 2,然后从pos位置到len-1位置排序,即7~2排序
				sort(nums.begin() + pos, nums.end());
				return;
			}
		}
	}
};
相应的结果如下:

  相信这个题带啊看懂了吧,如果还不明白的话,那么就得拿笔在纸上画画看吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值