题目描述
实现获取下一个排列的算法,算法需要将给定的数组,重新排列成下一个更大的排列(即组合出下一个更大的数字)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列。
题目思路
我们可以使用如下的思路来解决这个问题:
- 首先从后往前找到第一个升序排列的相邻元素对(
[nums[i]<nums[i+1]
),其中把相邻元素对中较小的下标记为i
- 如果
i
小于等于0
,那么说明这个数组是一个严格降序的数组,那么直接把数组反转并返回即可
- 如果
- 接下来从
[i+1, nums.length-1]
范围中,从后往前找到第一个>= nums[i]
的元素,下标记为j
- 交换
i
与j
下标的元素 - 将
[i+1, nums.length-1]
范围内的元素反转
实现代码
public void nextPermutation(int[] nums) {int i = nums.length-2;while (i>=0 && nums[i]>=nums[i+1]) {i--;}if (i < 0) {//如果 i 小于等于 0,说明这个数组是一个完全降序的数组//直接反转即可reverse(nums, 0, nums.length-1);return ;}//否则,从 [i+1, nums.length-1] 区间内,从后往前找到第一个比 nums[i] 大的数int j = nums.length-1;while (j>i && nums[j]<=nums[i]) {j--;}//交换两个元素的位置swap(nums, i, j);reverse(nums, i+1, nums.length-1);
}private void reverse(int[] nums, int start, int end) {while (start < end) {swap(nums, start, end);start++;end--;}
}private void swap(int[] nums, int i, int j) {int t = nums[i];nums[i] = nums[j];nums[j] = t;
}