Leetcode每日一题2020.11.10第31题:下一个排列

31.下一个排列

题目描述

在这里插入图片描述
在这里插入图片描述

知识点:字典序

	和字典的排序法相同,对于字符串而言,先按第一个字符排序,如果首字母相同,则按第二个字符排序,以此类推。
	本题情况下,以数字序列[1,2,3]为例,其排列按照字典序依次为:
					[1,2,3]  [1,3,2]
					[2,1,3]  [2,3,1]
					[3,1,2]  [3,2,1]
	特别的,最大的排列[3,2,1]的下一个排列为最小的排列[1,2,3]。

思路、算法及代码实现

		方法一:两遍扫描
						注意到下一个排列总是比当前排列要大,除非该排列已经是最大的排列。我们希望找到一种方法,能够找到一个大
						于当前序列的新序列,且变大的幅度尽可能小。具体地:
						1、我们需要将一个左边的“较小数”与一个右边的“较大数”交换,以能够让当前排列变大,从而得到下一个排列。
						2、同时我们要让这个“较小数”尽量靠右,而“较大数”尽可能小。当交换完成后,“较大数”右边的数需要按照升序重新
						      排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。		
						以排列[4,5,2,6,3,1]为例:
								1、我们能找到的符合条件的一对“较小数”与“较大数”的组合为2与3,满足“较小数”尽量靠右,而“较大数”尽可能									
							小。	
								2、当我们完成交换后排列变为[4,5,3,6,2,1],此时我们可以重排交换位置后的“较大数”右边的序列,序列变为
							[4,5,3,1,2,6]。
						具体地,我们这样描述该算法,对于长度为n的排列a:
								1、首先从后向前查找第一个顺序对(i,i+1),满足a[i]<a[i+1]。这样“较小数”即为a[i]。此时[i+1,n)必然是下降序
								列。
								2、如果找到了顺序对,那么在区间[i+1,n)中从后向前查找第一个元素j满足a[i]<a[j]。这样“较大数”即为a[j]。
								3、交换a[i]与a[j],此时可以证明区间[i+1,n)必为降序。我们可以直接使用双指针反转区间[i+1,n)使其变为升
								序,而无需对该区间进行排序。
								注意:如果在步骤1找不到顺序对,说明当前序列已经是一个降序序列,即最大的序列,我们直接跳过步骤2
								执行步骤3,即可得到最小的升序序列。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_51210480/article/details/109734852