31. Next Permutation

本文详细解析了下一个排列算法的问题背景及实现思路,通过实例演示如何找到一个数列的下一个字典序排列。介绍了如何在原地修改数组以获得下一个更大排列的方法,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

题目翻译:实现下一个排列,把数组重新排列成字典序中下一个更大的数字排列,如果找不到这样的排列,那么必须把它重新排列成可能的最低顺序(以升序排列),必须在原处替换,不能占用额外内存。下面是一些例子,输入在左边栏,相应的输出在右边栏。

好了,题目看完了,确实很懵==所以参考了其他的博客,原来这里的字典序是指全排列中的顺序,例如:

1,2,3

1,3,2

2,1,3

2,3,1

3,1,2

3,2,1

       这里1,2,3的下一个更大的数字排列是1,3,2,而1,3,2的下一个更大的数字排列是2,1,3...以此类推,所以,怎么寻找那些很长的数组的下一个更大的数字排列呢?

       沿用参考的博客中的例子:如果给定的nums是 6,5,4,8,7,5,1,因为它的子序列8,7,5,1是已经按降序排列好的,调换这里的任意一个数字都不可能使排列更大,所以从后往前搜索一直到4这个数字,这时4,8,7,5,1已经不是降序排列的子数组了,并且4<5,如果能将4和5调换,那么整体数组变成6,5,5,8,7,4,1,这个时候的排列的确比nums要大,但是不满足题目中的next greater这个条件,我们要找的是它的下一个更大的排列,所以在调换了4和这5之后,需要把子数组8,7,4,1按照升序排列,nums变为6,5,5,1,4,7,8,这个数组就是我们要找的下一个更大的数字排列组合了。

代码中设置了标志位,如果数组中存在数字调换的情况,则把标志位设为1,并且假设调换的数字索引为i,对i+1-len(数组长度)之间的数字排序即可。如果标志位没变化,说明整个数组是按降序排列的,把整个数组重新排序即可。

                int flag=0;
	        int len = nums.length;
		if(len==0){return;}
		for(int i=len-2;i>=0;i--){
			int m = nums[i];
			for(int j=len-1;j>i;j--){
				//如果从后往前遍历时找到了比nums[i]大的数字,就交换这两个数字
				if(m<nums[j]){
					nums[i] = nums[j];
					nums[j] = m;
					flag=1;
					break;
				}
			}
			if(flag==1){
				//sort的使用(数组名,排序起点,排序终点),(PS:只对i+1和len之间的数字排序,不包括下标为len的)
			Arrays.sort(nums, i+1,len);
			//排序完成后,跳出整个循环
			break;
		    }
		}
		
		//如果整个数组遍历完,flag没有变化,说明整个数组是降序排列的,要把它变为升序
		if(flag==0){
			Arrays.sort(nums);
		}

参考的博客链接:

博客链接1

博客链接2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值