码迷,mamicode.com
首页 > 其他好文 > 详细

笔试题44. LeetCode OJ (31)

时间:2016-05-03 18:46:29      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

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

     例如: 

   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 中,那么就是 5 4 7 5 3 2,意思就是找到比5 4 7 5 3 2大的数字中的最小的一个。用肉眼去看,是 5 5 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;
			}
		}
	}
};
相应的结果如下:

技术分享

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

笔试题44. LeetCode OJ (31)

标签:

原文地址:http://blog.csdn.net/zr1076311296/article/details/51296008

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!