LeetCode 31. 下一个排列(Java版)

题目

31. 下一个排列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DwJFp0kK-1575132872756)(index_files/addf2e96-4bd5-407d-ac76-fcee9fa13689.png)]

题解

数学家 Narayana Pandita 提出的思想

1 初始化一个index,从数组倒数第二个元素开始寻找第一个nums[index] < nums[index + 1],也就是寻找递减序列的前一个后一个元素,比如,一下这个数组,那么这个nums[index] = 2index也就是1

1 2 7 6 5 4

2 判断index是为-1
如果是-1 ,那么就代表这个是个递减序列,那么直接把数组全部颠倒就行。
如果不是-1,那么初始化firstBig,就继续从数组的最后开始寻找第一个大于num[index] 的位置,也就是nums[firstBig] > nums[index]
3 交换index和firstBig,这个主要是保证后面的递减序列的单调性。
4 颠倒交换后的单调递减序列,得到的就是答案

有个英文博文可以参考可以看这个文章
LeetCode 31 Next Permutation: Narayana Pandita’s algorithm
https://medium.com/@stevenpcurtis.sc/leetcode-31-next-permutation-narayana-panditas-algorithm-eb1dcb4686a7

public void nextPermutation(int[] nums) {
	if (nums == null || nums.length < 1) {
		return;
	}

	int len = nums.length;
	int index = len - 2;
	for (;index >= 0; --index) {
		if (nums[index] < nums[index + 1]) {
			break;
		}
	}
	// 这个nums本身就是个递减序列,直接颠倒,并且return。
	// 比如 7, 7, 6, 5,颠倒后 5,6,7,7。就是答案
	if (index == -1) {
		reverse(nums, 0, len - 1);
		return;
	}
	// 从最后一个元素往前寻找第一个大于nums[index]的位置。
	int firstBig = len - 1;
	for (; firstBig > index; firstBig--) {
		if (nums[firstBig] > nums[index]) {
			break;
		}
	}
	// 交换index和firstBig,这个主要是保证后面的递减序列的单调性。
	if (firstBig > index) {
		swap(nums, firstBig, index);
	}
	// 颠倒交换后的单调递减序列,得到的就是答案
	reverse(nums, index + 1, len - 1);
}

public void reverse(int[] arr, int start, int end) {
	while (start < end) {
		swap(arr, start, end);
		start++;
		end--;
	}
}

public void swap(int[] arr, int start, int end) {
	int temp = arr[start];
	arr[start] = arr[end];
	arr[end] = temp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值