LeetCode31. 下一个排列
Posted mx_info
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode31. 下一个排列相关的知识,希望对你有一定的参考价值。
LeetCode31. 下一个排列
题目描述
/**
* 实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
* <p>
* 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
* <p>
* 必须 原地 修改,只允许使用额外常数空间
*
*/
思路分析
- 获取数组元素排列的下一个更大的排列,需要考虑数组的三种情况
- 如果数组是降序的,则说明数组元素的排序为最大值,则下一个排列为数组元素的最小排列
- 如果数组是升序的,则只需要将最后两位数组元素交换即可
- 如果数组中元素有升序有降序,考虑如何获取下一个较大的排列
- 从右到左寻找第一次升序的两个元素,因为只有后边的元素比前边的一个元素大,交换两者的位置后才能实现比原来的排序大,如果靠右边的元素比左边一个元素小,则交换后排序更小
- 则需要记录升序的左侧元素的位置,在这个位置换上一个右侧的比他大的数
- 再考虑如何实现下一个较大的,即仅比当前排列大的
- 找到需要交换的的小数的索引后,再从右往左查找第一个比这个小数大的元素,记录位置
- 则交换这两个位置的元素即可
- 为保证仅比当前元素大,需要将交换后的右侧所有元素从小到大排序
源码及分析
public void nextPermutation(int[] nums) {
//数据校验
if (nums == null || nums.length == 0) {
throw new RuntimeException("数据输入有误~~");
} else if (nums.length == 1) {
nums = nums;
}
//考虑数组元素个数大于等于 2 的情况
//如果该数组元素是升序的,则只需要交换最后两位即可实现获取下一个更大的排序
//如果该数组元素不是升序的,若有升序有降序,则需要找到升序的两个元素,
// 再找到从右向前查找的比升序最小元素大的第一个数,交换位置,
// 将交换后后边的元素升序排列,实现后边元素最小,即下一个最小排序
//如果该数组元素是降序的,则说明该数组元素组成的序列已经最大,则下一个序列应该是升序排列的最小的数组
//定义min max为数组从右往左的第一次升序的两个数
int min = 0, max = 0, len = nums.length;
//定义flag,判断数组元素是否是降序的,若为降序的,则是最大排序,需要从小到大排序
boolean flag = true;
for (int i = len - 1; i > 0; i--) {
if (nums[i] > nums[i - 1]) {
max = i;
min = i - 1;
flag = false;
break;
}
}
//降序处理
if (flag) {
Arrays.sort(nums);
return;
}
//定义subMax保存从右到左的第一个大于min的值
int subMax = 0;
for (int i = len - 1; i > 0; i--) {
if (nums[i] > nums[min]) {
subMax = i;
break;
}
}
//交换min和subMax的值
int temp = nums[min];
nums[min] = nums[subMax];
nums[subMax] = temp;
//将min右边的元素排序
Arrays.sort(nums, min + 1, len);
}
以上是关于LeetCode31. 下一个排列的主要内容,如果未能解决你的问题,请参考以下文章